Changeset 241282 in webkit
- Timestamp:
- Feb 11, 2019 3:24:23 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 7 added
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r241278 r241282 1 2019-02-11 Daniel Bates <dabates@apple.com> 2 3 [iOS] Mouse/Touch/Pointer events are missing modifier keys 4 https://bugs.webkit.org/show_bug.cgi?id=191446 5 <rdar://problem/45929460> 6 7 Reviewed by Tim Horton. 8 9 Refactor existing iOS key events tests to share code. Add new tests to ensure touch and mouse events 10 have accurate modifier key details. 11 12 * fast/events/ios/key-events-meta-alt-combinations.html: 13 * fast/events/ios/resources/key-tester.js: 14 (computeSubsets.compareByModifierOrder): Deleted. 15 * fast/events/resources/compute-subsets.js: Added. 16 (computeSubsets.compareByOriginalArrayOrder): 17 (computeSubsets): 18 * fast/events/touch/ios/mouse-events-with-modifiers-expected.txt: Added. 19 * fast/events/touch/ios/mouse-events-with-modifiers.html: Added. 20 * fast/events/touch/ios/pointer-events-with-modifiers-expected.txt: Added. 21 * fast/events/touch/ios/pointer-events-with-modifiers.html: Added. 22 * fast/events/touch/ios/touch-events-with-modifiers-expected.txt: Added. 23 * fast/events/touch/ios/touch-events-with-modifiers.html: Added. 24 * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Update expected result 25 due to changes to ui-helper.js. 26 * http/tests/security/anchor-download-block-crossorigin-expected.txt: Ditto. 27 * platform/ios/TestExpectations: 28 * resources/ui-helper.js: 29 (window.UIHelper.tapAt.return.new.Promise): 30 (window.UIHelper.tapAt): 31 (window.UIHelper.stylusTapAt.return.new.Promise): 32 (window.UIHelper.stylusTapAt): 33 1 34 2019-02-11 Commit Queue <commit-queue@webkit.org> 2 35 -
trunk/LayoutTests/fast/events/ios/key-events-meta-alt-combinations.html
r241278 r241282 3 3 <head> 4 4 <script src="../../../resources/ui-helper.js"></script> 5 <script src="../resources/compute-subsets.js"></script> 5 6 <script src="resources/key-tester.js"></script> 6 7 <script> 7 8 const modiferKeySubsetsToTest = computeSubsets(["metaKey", "altKey"]); 8 9 for (const k of keysExcludingDeadAndSkippedKeys) { 9 for (const modifiers of modiferKeySubsetsToTest)10 for (const modifiers of computeSubsets(modifierKeys)) 10 11 tests.push(new KeyCommand(k, modifiers)); 11 12 } -
trunk/LayoutTests/fast/events/ios/resources/key-tester.js
r241278 r241282 54 54 } 55 55 56 // This algorithm runs in O(2^N).57 function computeSubsets(anArray)58 {59 function compareByModifierOrder(a, b) {60 if (a.length < b.length)61 return -1;62 if (a.length > b.length)63 return 1;64 for (let i = 0; i < a.length; ++i) {65 let rankA = anArray.indexOf(a[i]);66 let rankB = anArray.indexOf(b[i]);67 if (rankA < rankB)68 return -1;69 if (rankA > rankB)70 return 1;71 }72 return 0;73 }74 let result = [];75 const numberOfNonEmptyPermutations = (1 << anArray.length) - 1;76 // For each ordinal 1, 2, ... numberOfNonEmptyPermutations we look at its binary representation77 // and generate a permutation that consists of the entries in anArray at the indices where there78 // is a one bit in the binary representation. For example, suppose anArray = ["metaKey", "altKey", "ctrlKey"].79 // To generate the 5th permutation we look at the binary representation of i = 5 => 0b101. And80 // compute the permutation to be [ anArray[0], anArray[2] ] = [ "metaKey", "ctrlKey" ] because81 // the 0th and 2nd bits are ones in the binary representation.82 for (let i = 1; i <= numberOfNonEmptyPermutations; ++i) {83 let temp = [];84 for (let bitmask = i, j = 0; bitmask; bitmask = Math.floor(bitmask / 2), ++j) {85 if (bitmask % 2)86 temp.push(anArray[j]);87 }88 result.push(temp);89 }90 return result.sort(compareByModifierOrder);91 }92 93 56 const keys = new Set("abcdefghijklmnopqrstuvwxyz0123456789-=[]\\;',./".split("")); 94 57 const deadKeys = new Set("`euin".split("")); … … 118 81 119 82 const modifierKeys = ["metaKey", "altKey", "ctrlKey", "shiftKey"]; 120 const modiferKeySubsets = computeSubsets(modifierKeys);121 83 122 84 let tests = []; -
trunk/LayoutTests/http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt
r241278 r241282 1 CONSOLE MESSAGE: line 10 7: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution.2 CONSOLE MESSAGE: line 10 7: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution.3 CONSOLE MESSAGE: line 10 7: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.4 CONSOLE MESSAGE: line 10 7: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.5 CONSOLE MESSAGE: line 10 7: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution.6 CONSOLE MESSAGE: line 10 7: adddestination could not be converted to a valid HTTP-family URL.7 CONSOLE MESSAGE: line 10 7: adddestination could not be converted to a valid HTTP-family URL.8 CONSOLE MESSAGE: line 10 7: adddestination could not be converted to a valid HTTP-family URL.9 CONSOLE MESSAGE: line 10 7: Both adcampaignid and addestination need to be set for Ad Click Attribution to work.10 CONSOLE MESSAGE: line 10 7: Both adcampaignid and addestination need to be set for Ad Click Attribution to work.1 CONSOLE MESSAGE: line 108: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution. 2 CONSOLE MESSAGE: line 108: adcampaignid must have a non-negative value less than 64 for Ad Click Attribution. 3 CONSOLE MESSAGE: line 108: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution. 4 CONSOLE MESSAGE: line 108: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution. 5 CONSOLE MESSAGE: line 108: adcampaignid can not be converted to a non-negative integer which is required for Ad Click Attribution. 6 CONSOLE MESSAGE: line 108: adddestination could not be converted to a valid HTTP-family URL. 7 CONSOLE MESSAGE: line 108: adddestination could not be converted to a valid HTTP-family URL. 8 CONSOLE MESSAGE: line 108: adddestination could not be converted to a valid HTTP-family URL. 9 CONSOLE MESSAGE: line 108: Both adcampaignid and addestination need to be set for Ad Click Attribution to work. 10 CONSOLE MESSAGE: line 108: Both adcampaignid and addestination need to be set for Ad Click Attribution to work. 11 11 Test for validity of ad click attribution attributes on anchor tags. 12 12 -
trunk/LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt
r241278 r241282 1 CONSOLE MESSAGE: line 10 7: The download attribute on anchor was ignored because its href URL has a different security origin.1 CONSOLE MESSAGE: line 108: The download attribute on anchor was ignored because its href URL has a different security origin. 2 2 Tests that the download attribute is ignored if the link is cross origin. 3 3 -
trunk/LayoutTests/platform/ios/TestExpectations
r241278 r241282 3211 3211 webkit.org/b/153337 pageoverlay/overlay-large-document-scrolled.html [ Pass Failure ] 3212 3212 webkit.org/b/153337 pageoverlay/overlay-large-document.html [ Pass Failure ] 3213 3214 # FIXME: Unskip the following test once we have the fix for <rdar://problem/45970040>. 3215 fast/events/touch/ios/touch-events-with-modifiers.html [ Skip ] 3216 fast/events/touch/ios/mouse-events-with-modifiers.html [ Skip ] 3217 fast/events/touch/ios/pointer-events-with-modifiers.html [ Skip ] -
trunk/LayoutTests/resources/ui-helper.js
r241278 r241282 30 30 } 31 31 32 static tapAt(x, y )32 static tapAt(x, y, modifiers=[]) 33 33 { 34 34 console.assert(this.isIOS()); 35 35 36 36 if (!this.isWebKit2()) { 37 console.assert(!modifiers || !modifiers.length); 37 38 eventSender.addTouchPoint(x, y); 38 39 eventSender.touchStart(); … … 44 45 return new Promise((resolve) => { 45 46 testRunner.runUIScript(` 46 uiController.singleTapAtPoint (${x}, ${y}, function() {47 uiController.singleTapAtPointWithModifiers(${x}, ${y}, ${JSON.stringify(modifiers)}, function() { 47 48 uiController.uiScriptComplete(); 48 49 });`, resolve); … … 566 567 } 567 568 568 static stylusTapAt(x, y )569 static stylusTapAt(x, y, modifiers=[]) 569 570 { 570 571 if (!this.isWebKit2()) … … 573 574 return new Promise((resolve) => { 574 575 testRunner.runUIScript(` 575 uiController.stylusTapAtPoint (${x}, ${y}, 2, 1, 0.5, function() {576 uiController.stylusTapAtPointWithModifiers(${x}, ${y}, 2, 1, 0.5, ${JSON.stringify(modifiers)}, function() { 576 577 uiController.uiScriptComplete(); 577 578 });`, resolve); -
trunk/Source/WebCore/ChangeLog
r241281 r241282 1 2019-02-11 Daniel Bates <dabates@apple.com> 2 3 [iOS] Mouse/Touch/Pointer events are missing modifier keys 4 https://bugs.webkit.org/show_bug.cgi?id=191446 5 <rdar://problem/45929460> 6 7 Reviewed by Tim Horton. 8 9 Extract the modifier flags from the WebEvent. This code is only used by Legacy WebKit 10 on iOS and we will need to fix <rdar://problem/47929759> in order for modifier flags 11 to be passed to WebKit. 12 13 Tests: fast/events/touch/ios/mouse-events-with-modifiers.html 14 fast/events/touch/ios/pointer-events-with-modifiers.html 15 fast/events/touch/ios/touch-events-with-modifiers.html 16 17 * platform/ios/PlatformEventFactoryIOS.mm: 18 (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder): 19 * platform/ios/WebEvent.h: 20 * platform/ios/WebEvent.mm: 21 (-[WebEvent initWithMouseEventType:timeStamp:location:]): 22 (-[WebEvent initWithMouseEventType:timeStamp:location:modifiers:]): 23 1 24 2019-02-11 Jer Noble <jer.noble@apple.com> 2 25 -
trunk/Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm
r241278 r241282 96 96 m_button = LeftButton; // This has always been the LeftButton on iOS. 97 97 m_clickCount = 1; // This has always been 1 on iOS. 98 m_modifiers = modifiersForEvent(event); 98 99 } 99 100 }; -
trunk/Source/WebCore/platform/ios/WebEvent.h
r241278 r241282 140 140 } 141 141 142 // Deprecated. Remove once UIKit adopts -initWithMouseEventType taking modifiers. 142 143 - (WebEvent *)initWithMouseEventType:(WebEventType)type 143 144 timeStamp:(CFTimeInterval)timeStamp 144 145 location:(CGPoint)point; 146 147 - (WebEvent *)initWithMouseEventType:(WebEventType)type timeStamp:(CFTimeInterval)timeStamp location:(CGPoint)point modifiers:(WebEventFlags)modifiers; 145 148 146 149 - (WebEvent *)initWithScrollWheelEventWithTimeStamp:(CFTimeInterval)timeStamp -
trunk/Source/WebCore/platform/ios/WebEvent.mm
r241278 r241282 50 50 @synthesize wasHandled = _wasHandled; 51 51 52 - (WebEvent *)initWithMouseEventType:(WebEventType)type 53 timeStamp:(CFTimeInterval)timeStamp 54 location:(CGPoint)point 52 - (WebEvent *)initWithMouseEventType:(WebEventType)type timeStamp:(CFTimeInterval)timeStamp location:(CGPoint)point 53 { 54 return [self initWithMouseEventType:type timeStamp:timeStamp location:point modifiers:0]; 55 } 56 57 - (WebEvent *)initWithMouseEventType:(WebEventType)type timeStamp:(CFTimeInterval)timeStamp location:(CGPoint)point modifiers:(WebEventFlags)modifiers 55 58 { 56 59 self = [super init]; 57 60 if (!self) 58 61 return nil; 59 60 62 _type = type; 61 63 _timestamp = timeStamp; 62 63 64 _locationInWindow = point; 64 65 _modifierFlags = modifiers; 65 66 return self; 66 67 } -
trunk/Source/WebKit/ChangeLog
r241281 r241282 1 2019-02-11 Daniel Bates <dabates@apple.com> 2 3 [iOS] Mouse/Touch/Pointer events are missing modifier keys 4 https://bugs.webkit.org/show_bug.cgi?id=191446 5 <rdar://problem/45929460> 6 7 Reviewed by Tim Horton. 8 9 Make use of UIKit SPI to retreive the modifier flags when dispatching mouse and touch events. 10 Add new WebKit SPI for iOS, -[WKNavigationAction modifierFlags], to retrieve the the modifier 11 flags held when a navigation action was initiated. 12 13 * Platform/spi/ios/UIKitSPI.h: Expose SPI. 14 * Shared/NativeWebTouchEvent.h: Re-arrange macro guards so that we can expose the helper function 15 WebKit::webEventModifierFlags(). This is a bit more involved that usual since this header is included 16 from both C++ and Objective-C source files. It only makes sense to expose this function when 17 compiling as part of an Objective-C source file. 18 * Shared/ios/NativeWebTouchEventIOS.mm: 19 (WebKit::NativeWebTouchEvent::NativeWebTouchEvent): Modified to take the modifier flags held down 20 when the platform touch event was received and pass them through to the base constructor. 21 (WebKit::webEventModifierFlags): Added. Converts from the platform-speciifc UIKeyModifierFlags to 22 OptionSet<WebKit::WebEvent::Modifier>. 23 * Shared/ios/WebIOSEventFactory.h: 24 * Shared/ios/WebIOSEventFactory.mm: 25 (WebIOSEventFactory::toUIKeyModifierFlags): Added. Converts from OptionSet<WebKit::WebEvent::Modifier> 26 to the platform-specific UIKeyModifierFlags. 27 * UIProcess/API/Cocoa/WKNavigationAction.mm: 28 (-[WKNavigationAction modifierFlags]): Added. 29 * UIProcess/API/Cocoa/WKNavigationActionPrivate.h: 30 * UIProcess/WebPageProxy.h: 31 * UIProcess/ios/WKContentViewInteraction.h: 32 * UIProcess/ios/WKContentViewInteraction.mm: 33 (gestureRecognizerModifierFlags): Added. 34 35 (-[WKContentView _webTouchEventsRecognized:]): 36 (-[WKContentView _highlightLongPressRecognized:]): 37 (-[WKContentView _twoFingerSingleTapGestureRecognized:]): 38 (-[WKContentView _singleTapCommited:]): 39 Pass modifier flags through. 40 41 (-[WKContentView _attemptClickAtLocation:modifierFlags:]): Added. 42 (-[WKContentView actionSheetAssistant:openElementAtLocation:]): This is invoked when a person opens a link 43 via the action sheet. We don't have access to the modifier flags to pass. It also seems like an implementation 44 detail that this action is implemented via mouse click and we should re-evaluate this decision in light of 45 the fact tht the action sheet is browser UI and we tend to be very reserved on what UI actions are visible 46 to the page. On Mac, opening a link via the context menu is not visible to the page, at least from a mouse 47 event perspective. 48 (webEventFlagsForUIKeyModifierFlags): Added. 49 (-[WKContentView _hoverGestureRecognizerChanged:]): Pass modifier flags through. 50 (-[WKContentView _attemptClickAtLocation:]): Deleted. 51 * UIProcess/ios/WebPageProxyIOS.mm: 52 (WebKit::WebPageProxy::handleTwoFingerTapAtPoint): 53 (WebKit::WebPageProxy::commitPotentialTap): 54 (WebKit::WebPageProxy::handleTap): 55 * WebProcess/WebPage/WebPage.h: 56 * WebProcess/WebPage/WebPage.messages.in: 57 * WebProcess/WebPage/ios/WebPageIOS.mm: 58 (WebKit::WebPage::handleSyntheticClick): 59 (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): 60 (WebKit::WebPage::completeSyntheticClick): 61 (WebKit::WebPage::handleTap): 62 (WebKit::WebPage::handleTwoFingerTapAtPoint): 63 (WebKit::WebPage::commitPotentialTap): 64 Pass modifier flags through. 65 1 66 2019-02-11 Jer Noble <jer.noble@apple.com> 2 67 -
trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h
r241278 r241282 1038 1038 @end 1039 1039 1040 @interface UIGestureRecognizer (Staging_45970040) 1041 @property (nonatomic, readonly, getter=_modifierFlags) UIKeyModifierFlags modifierFlags; 1042 @end 1043 1040 1044 @interface UIPhysicalKeyboardEvent : UIPressesEvent 1041 1045 @end -
trunk/Source/WebKit/Shared/NativeWebTouchEvent.h
r241278 r241282 24 24 */ 25 25 26 #ifndef NativeWebTouchEvent_h 27 #define NativeWebTouchEvent_h 26 #pragma once 27 28 #include "WebEvent.h" 28 29 29 30 #if ENABLE(TOUCH_EVENTS) 30 31 31 #include "WebEvent.h"32 33 32 #if PLATFORM(IOS_FAMILY) 33 #if defined(__OBJC__) 34 #include <UIKit/UIKit.h> 34 35 struct _UIWebTouchEvent; 36 #endif 35 37 #elif PLATFORM(GTK) 36 38 #include <WebCore/GUniquePtrGtk.h> … … 39 41 #endif 40 42 43 #endif // ENABLE(TOUCH_EVENTS) 44 41 45 namespace WebKit { 46 47 #if ENABLE(TOUCH_EVENTS) 42 48 43 49 class NativeWebTouchEvent : public WebTouchEvent { 44 50 public: 45 51 #if PLATFORM(IOS_FAMILY) 46 explicit NativeWebTouchEvent(const _UIWebTouchEvent*); 52 #if defined(__OBJC__) 53 explicit NativeWebTouchEvent(const _UIWebTouchEvent*, UIKeyModifierFlags); 54 #endif 47 55 #elif PLATFORM(GTK) 48 56 NativeWebTouchEvent(GdkEvent*, Vector<WebPlatformTouchPoint>&&); … … 57 65 58 66 private: 59 #if PLATFORM(IOS_FAMILY) 67 #if PLATFORM(IOS_FAMILY) && defined(__OBJC__) 60 68 Vector<WebPlatformTouchPoint> extractWebTouchPoint(const _UIWebTouchEvent*); 61 69 #endif … … 68 76 }; 69 77 70 } // namespace WebKit71 72 78 #endif // ENABLE(TOUCH_EVENTS) 73 79 74 #endif // NativeWebTouchEvent_h 80 #if PLATFORM(IOS_FAMILY) && defined(__OBJC__) 81 OptionSet<WebEvent::Modifier> webEventModifierFlags(UIKeyModifierFlags); 82 #endif 83 84 } // namespace WebKit -
trunk/Source/WebKit/Shared/ios/NativeWebTouchEventIOS.mm
r241278 r241282 27 27 #import "NativeWebTouchEvent.h" 28 28 29 #if PLATFORM(IOS_FAMILY) && ENABLE(TOUCH_EVENTS)29 #if PLATFORM(IOS_FAMILY) 30 30 31 31 #import "UIKitSPI.h" 32 #import "WebEvent.h"33 32 #import <UIKit/UITouch.h> 34 33 #import <WebCore/IntPoint.h> … … 36 35 37 36 namespace WebKit { 37 38 #if ENABLE(TOUCH_EVENTS) 38 39 39 40 static inline WebEvent::Type webEventTypeForUIWebTouchEventType(UIWebTouchEventType type) … … 118 119 } 119 120 120 NativeWebTouchEvent::NativeWebTouchEvent(const _UIWebTouchEvent* event )121 NativeWebTouchEvent::NativeWebTouchEvent(const _UIWebTouchEvent* event, UIKeyModifierFlags flags) 121 122 : WebTouchEvent( 122 123 webEventTypeForUIWebTouchEventType(event->type), 123 OptionSet<Modifier> { },124 webEventModifierFlags(flags), 124 125 WallTime::fromRawSeconds(event->timestamp), 125 126 extractWebTouchPoint(event), … … 136 137 } 137 138 139 #endif // ENABLE(TOUCH_EVENTS) 140 141 OptionSet<WebEvent::Modifier> webEventModifierFlags(UIKeyModifierFlags flags) 142 { 143 OptionSet<WebEvent::Modifier> modifiers; 144 if (flags & UIKeyModifierShift) 145 modifiers.add(WebEvent::Modifier::ShiftKey); 146 if (flags & UIKeyModifierControl) 147 modifiers.add(WebEvent::Modifier::ControlKey); 148 if (flags & UIKeyModifierAlternate) 149 modifiers.add(WebEvent::Modifier::AltKey); 150 if (flags & UIKeyModifierCommand) 151 modifiers.add(WebEvent::Modifier::MetaKey); 152 if (flags & UIKeyModifierAlphaShift) 153 modifiers.add(WebEvent::Modifier::CapsLockKey); 154 return modifiers; 155 } 156 138 157 } // namespace WebKit 139 158 140 #endif // PLATFORM(IOS_FAMILY) && ENABLE(TOUCH_EVENTS)159 #endif // PLATFORM(IOS_FAMILY) -
trunk/Source/WebKit/Shared/ios/WebIOSEventFactory.h
r241278 r241282 24 24 */ 25 25 26 #ifndef WebIOSEventFactory_h 27 #define WebIOSEventFactory_h 26 #pragma once 28 27 29 28 #if PLATFORM(IOS_FAMILY) 30 29 31 30 #import "WebEvent.h" 31 #import <UIKit/UIKit.h> 32 32 #import <WebCore/WebEvent.h> 33 33 … … 36 36 static WebKit::WebKeyboardEvent createWebKeyboardEvent(::WebEvent *); 37 37 static WebKit::WebMouseEvent createWebMouseEvent(::WebEvent *); 38 39 static UIKeyModifierFlags toUIKeyModifierFlags(OptionSet<WebKit::WebEvent::Modifier>); 38 40 }; 39 41 40 42 #endif // PLATFORM(IOS_FAMILY) 41 42 #endif // WebIOSEventFactory_h -
trunk/Source/WebKit/Shared/ios/WebIOSEventFactory.mm
r241278 r241282 31 31 #import <WebCore/KeyEventCodesIOS.h> 32 32 #import <WebCore/PlatformEventFactoryIOS.h> 33 34 UIKeyModifierFlags WebIOSEventFactory::toUIKeyModifierFlags(OptionSet<WebKit::WebEvent::Modifier> modifiers) 35 { 36 UIKeyModifierFlags modifierFlags = 0; 37 if (modifiers.contains(WebKit::WebEvent::Modifier::ShiftKey)) 38 modifierFlags |= UIKeyModifierShift; 39 if (modifiers.contains(WebKit::WebEvent::Modifier::ControlKey)) 40 modifierFlags |= UIKeyModifierControl; 41 if (modifiers.contains(WebKit::WebEvent::Modifier::AltKey)) 42 modifierFlags |= UIKeyModifierAlternate; 43 if (modifiers.contains(WebKit::WebEvent::Modifier::MetaKey)) 44 modifierFlags |= UIKeyModifierCommand; 45 if (modifiers.contains(WebKit::WebEvent::Modifier::CapsLockKey)) 46 modifierFlags |= UIKeyModifierAlphaShift; 47 return modifierFlags; 48 } 33 49 34 50 static OptionSet<WebKit::WebEvent::Modifier> modifiersForEvent(::WebEvent *event) -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationAction.mm
r241278 r241282 37 37 #import <wtf/RetainPtr.h> 38 38 39 #if PLATFORM(IOS_FAMILY) 40 #import "WebIOSEventFactory.h" 41 #endif 42 39 43 @implementation WKNavigationAction 40 44 … … 128 132 129 133 #if PLATFORM(MAC) 134 130 135 - (NSEventModifierFlags)modifierFlags 131 136 { … … 137 142 return WebKit::WebEventFactory::toNSButtonNumber(_navigationAction->mouseButton()); 138 143 } 144 145 #else 146 147 - (UIKeyModifierFlags)modifierFlags 148 { 149 return WebIOSEventFactory::toUIKeyModifierFlags(_navigationAction->modifiers()); 150 } 151 139 152 #endif 140 153 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationActionPrivate.h
r241278 r241282 32 32 33 33 #if TARGET_OS_IPHONE 34 #include <UIKit/UIKit.h> 35 34 36 typedef NS_ENUM(NSInteger, WKSyntheticClickType) { 35 37 WKSyntheticClickTypeNoTap, … … 54 56 @property (nonatomic, readonly) WKSyntheticClickType _syntheticClickType WK_API_AVAILABLE(ios(10.0)); 55 57 @property (nonatomic, readonly) CGPoint _clickLocationInRootViewCoordinates WK_API_AVAILABLE(ios(11.0)); 58 59 @property (nonatomic, readonly) UIKeyModifierFlags modifierFlags WK_API_AVAILABLE(ios(WK_IOS_TBA)); 56 60 #endif 57 61 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r241278 r241282 81 81 #include <WebCore/MediaPlaybackTargetContext.h> 82 82 #include <WebCore/MediaProducer.h> 83 #include <WebCore/PlatformEvent.h> 83 84 #include <WebCore/PlatformScreen.h> 84 85 #include <WebCore/PointerID.h> … … 673 674 void contentSizeCategoryDidChange(const String& contentSizeCategory); 674 675 void getSelectionContext(WTF::Function<void(const String&, const String&, const String&, CallbackBase::Error)>&&); 675 void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);676 void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t requestID); 676 677 void handleStylusSingleTapAtPoint(const WebCore::IntPoint&, uint64_t requestID); 677 678 void setForceAlwaysUserScalable(bool); … … 1172 1173 1173 1174 void potentialTapAtPosition(const WebCore::FloatPoint&, uint64_t& requestID); 1174 void commitPotentialTap( uint64_t layerTreeTransactionIdAtLastTouchStart);1175 void commitPotentialTap(OptionSet<WebKit::WebEvent::Modifier>, uint64_t layerTreeTransactionIdAtLastTouchStart); 1175 1176 void cancelPotentialTap(); 1176 1177 void tapHighlightAtPosition(const WebCore::FloatPoint&, uint64_t& requestID); 1177 void handleTap(const WebCore::FloatPoint&, uint64_t layerTreeTransactionIdAtLastTouchStart);1178 void handleTap(const WebCore::FloatPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t layerTreeTransactionIdAtLastTouchStart); 1178 1179 1179 1180 void inspectorNodeSearchMovedToPosition(const WebCore::FloatPoint&); -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r241278 r241282 407 407 - (BOOL)_interpretKeyEvent:(::WebEvent *)theEvent isCharEvent:(BOOL)isCharEvent; 408 408 - (void)_positionInformationDidChange:(const WebKit::InteractionInformationAtPosition&)info; 409 - (void)_attemptClickAtLocation:(CGPoint)location ;409 - (void)_attemptClickAtLocation:(CGPoint)location modifierFlags:(UIKeyModifierFlags)modifierFlags; 410 410 - (void)_willStartScrollingOrZooming; 411 411 - (void)_didScroll; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r241278 r241282 1161 1161 #endif 1162 1162 1163 inline static UIKeyModifierFlags gestureRecognizerModifierFlags(UIGestureRecognizer *recognizer) 1164 { 1165 return [recognizer respondsToSelector:@selector(_modifierFlags)] ? recognizer.modifierFlags : 0; 1166 } 1167 1163 1168 - (void)_webTouchEventsRecognized:(UIWebTouchEventsGestureRecognizer *)gestureRecognizer 1164 1169 { … … 1173 1178 1174 1179 #if ENABLE(TOUCH_EVENTS) 1175 WebKit::NativeWebTouchEvent nativeWebTouchEvent (lastTouchEvent);1180 WebKit::NativeWebTouchEvent nativeWebTouchEvent { lastTouchEvent, gestureRecognizerModifierFlags(gestureRecognizer) }; 1176 1181 nativeWebTouchEvent.setCanPreventNativeGestures(!_canSendTouchEventsAsynchronously || [gestureRecognizer isDefaultPrevented]); 1177 1182 … … 2056 2061 case UIGestureRecognizerStateEnded: 2057 2062 if (_highlightLongPressCanClick && _positionInformation.isElement) { 2058 [self _attemptClickAtLocation: [gestureRecognizer startPoint]];2063 [self _attemptClickAtLocation:gestureRecognizer.startPoint modifierFlags:gestureRecognizerModifierFlags(gestureRecognizer)]; 2059 2064 [self _finishInteraction]; 2060 2065 } else … … 2075 2080 _isTapHighlightIDValid = YES; 2076 2081 _isExpectingFastSingleTapCommit = YES; 2077 _page->handleTwoFingerTapAtPoint(WebCore::roundedIntPoint(gestureRecognizer.centroid), ++_latestTapID);2082 _page->handleTwoFingerTapAtPoint(WebCore::roundedIntPoint(gestureRecognizer.centroid), WebKit::webEventModifierFlags(gestureRecognizerModifierFlags(gestureRecognizer)), ++_latestTapID); 2078 2083 } 2079 2084 … … 2197 2202 2198 2203 [_inputPeripheral endEditing]; 2199 _page->commitPotentialTap( _layerTreeTransactionIdAtLastTouchStart);2204 _page->commitPotentialTap(WebKit::webEventModifierFlags(gestureRecognizerModifierFlags(gestureRecognizer)), _layerTreeTransactionIdAtLastTouchStart); 2200 2205 2201 2206 if (!_isExpectingFastSingleTapCommit) … … 2230 2235 } 2231 2236 2232 - (void)_attemptClickAtLocation:(CGPoint)location 2237 - (void)_attemptClickAtLocation:(CGPoint)location modifierFlags:(UIKeyModifierFlags)modifierFlags 2233 2238 { 2234 2239 if (![self isFirstResponder]) { … … 2239 2244 2240 2245 [_inputPeripheral endEditing]; 2241 _page->handleTap(location, _layerTreeTransactionIdAtLastTouchStart);2246 _page->handleTap(location, WebKit::webEventModifierFlags(modifierFlags), _layerTreeTransactionIdAtLastTouchStart); 2242 2247 } 2243 2248 … … 5412 5417 - (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant openElementAtLocation:(CGPoint)location 5413 5418 { 5414 [self _attemptClickAtLocation:location ];5419 [self _attemptClickAtLocation:location modifierFlags:0]; 5415 5420 } 5416 5421 … … 6419 6424 } 6420 6425 6426 static WebEventFlags webEventFlagsForUIKeyModifierFlags(UIKeyModifierFlags flags) 6427 { 6428 WebEventFlags eventFlags = 0; 6429 if (flags & UIKeyModifierShift) 6430 eventFlags |= WebEventFlagMaskLeftShiftKey; 6431 if (flags & UIKeyModifierControl) 6432 eventFlags |= WebEventFlagMaskLeftControlKey; 6433 if (flags & UIKeyModifierAlternate) 6434 eventFlags |= WebEventFlagMaskLeftOptionKey; 6435 if (flags & UIKeyModifierCommand) 6436 eventFlags |= WebEventFlagMaskLeftCommandKey; 6437 if (flags & UIKeyModifierAlphaShift) 6438 eventFlags |= WebEventFlagMaskLeftCapsLockKey; 6439 return eventFlags; 6440 } 6441 6421 6442 - (void)_hoverGestureRecognizerChanged:(UIGestureRecognizer *)gestureRecognizer 6422 6443 { … … 6440 6461 } 6441 6462 6442 auto event = adoptNS([[::WebEvent alloc] initWithMouseEventType:WebEventMouseMoved timeStamp:timestamp location:point ]);6463 auto event = adoptNS([[::WebEvent alloc] initWithMouseEventType:WebEventMouseMoved timeStamp:timestamp location:point modifiers:webEventFlagsForUIKeyModifierFlags(gestureRecognizerModifierFlags(gestureRecognizer))]); 6443 6464 _page->handleMouseEvent(WebKit::NativeWebMouseEvent(event.get())); 6444 6465 } -
trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
r241278 r241282 597 597 } 598 598 599 void WebPageProxy::handleTwoFingerTapAtPoint(const WebCore::IntPoint& point, uint64_t requestID)600 { 601 process().send(Messages::WebPage::HandleTwoFingerTapAtPoint(point, requestID), m_pageID);599 void WebPageProxy::handleTwoFingerTapAtPoint(const WebCore::IntPoint& point, OptionSet<WebEvent::Modifier> modifiers, uint64_t requestID) 600 { 601 process().send(Messages::WebPage::HandleTwoFingerTapAtPoint(point, modifiers, requestID), m_pageID); 602 602 } 603 603 … … 828 828 } 829 829 830 void WebPageProxy::commitPotentialTap( uint64_t layerTreeTransactionIdAtLastTouchStart)831 { 832 process().send(Messages::WebPage::CommitPotentialTap( layerTreeTransactionIdAtLastTouchStart), m_pageID);830 void WebPageProxy::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t layerTreeTransactionIdAtLastTouchStart) 831 { 832 process().send(Messages::WebPage::CommitPotentialTap(modifiers, layerTreeTransactionIdAtLastTouchStart), m_pageID); 833 833 } 834 834 … … 843 843 } 844 844 845 void WebPageProxy::handleTap(const FloatPoint& location, uint64_t layerTreeTransactionIdAtLastTouchStart)846 { 847 process().send(Messages::WebPage::HandleTap(roundedIntPoint(location), layerTreeTransactionIdAtLastTouchStart), m_pageID);845 void WebPageProxy::handleTap(const FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, uint64_t layerTreeTransactionIdAtLastTouchStart) 846 { 847 process().send(Messages::WebPage::HandleTap(roundedIntPoint(location), modifiers, layerTreeTransactionIdAtLastTouchStart), m_pageID); 848 848 } 849 849 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r241281 r241282 614 614 bool hasStablePageScaleFactor() const { return m_hasStablePageScaleFactor; } 615 615 616 void handleTap(const WebCore::IntPoint&, uint64_t lastLayerTreeTransactionId);616 void handleTap(const WebCore::IntPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t lastLayerTreeTransactionId); 617 617 void potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoint&); 618 void commitPotentialTap( uint64_t lastLayerTreeTransactionId);618 void commitPotentialTap(OptionSet<WebKit::WebEvent::Modifier>, uint64_t lastLayerTreeTransactionId); 619 619 void commitPotentialTapFailed(); 620 620 void cancelPotentialTap(); … … 662 662 void updateSelectionAppearance(); 663 663 void getSelectionContext(CallbackID); 664 void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);664 void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t requestID); 665 665 void handleStylusSingleTapAtPoint(const WebCore::IntPoint&, uint64_t requestID); 666 666 void getRectsForGranularityWithSelectionOffset(uint32_t, int32_t, CallbackID); … … 1185 1185 void getFocusedElementInformation(FocusedElementInformation&); 1186 1186 void platformInitializeAccessibility(); 1187 void handleSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location );1188 void completeSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location, WebCore::SyntheticClickType);1187 void handleSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>); 1188 void completeSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::SyntheticClickType); 1189 1189 void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*); 1190 1190 void resetTextAutosizing(); … … 1768 1768 WebCore::FloatPoint m_pendingSyntheticClickLocation; 1769 1769 WebCore::FloatRect m_previousExposedContentRect; 1770 OptionSet<WebKit::WebEvent::Modifier> m_pendingSyntheticClickModifiers; 1770 1771 FocusedElementIdentifier m_currentFocusedElementIdentifier { 0 }; 1771 1772 Optional<DynamicViewportSizeUpdateID> m_pendingDynamicViewportSizeUpdateID; -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
r241278 r241282 52 52 DynamicViewportSizeUpdate(WebCore::FloatSize viewLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID) 53 53 54 HandleTap(WebCore::IntPoint point, uint64_t lastLayerTreeTransactionId)54 HandleTap(WebCore::IntPoint point, OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId) 55 55 PotentialTapAtPosition(uint64_t requestID, WebCore::FloatPoint point) 56 CommitPotentialTap( uint64_t lastLayerTreeTransactionId)56 CommitPotentialTap(OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId) 57 57 CancelPotentialTap() 58 58 TapHighlightAtPosition(uint64_t requestID, WebCore::FloatPoint point) … … 99 99 GetSelectionContext(WebKit::CallbackID callbackID) 100 100 SetAllowsMediaDocumentInlinePlayback(bool allows) 101 HandleTwoFingerTapAtPoint(WebCore::IntPoint point, uint64_t requestID)101 HandleTwoFingerTapAtPoint(WebCore::IntPoint point, OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t requestID) 102 102 HandleStylusSingleTapAtPoint(WebCore::IntPoint point, uint64_t requestID) 103 103 SetForceAlwaysUserScalable(bool userScalable) -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r241281 r241282 528 528 } 529 529 530 void WebPage::handleSyntheticClick(Node* nodeRespondingToClick, const WebCore::FloatPoint& location )530 void WebPage::handleSyntheticClick(Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers) 531 531 { 532 532 IntPoint roundedAdjustedPoint = roundedIntPoint(location); … … 537 537 WKStartObservingDOMTimerScheduling(); 538 538 539 mainframe.eventHandler().mouseMoved(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, NoButton, PlatformEvent::MouseMoved, 0, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap)); 539 // FIXME: Pass caps lock state. 540 bool shiftKey = modifiers.contains(WebEvent::Modifier::ShiftKey); 541 bool ctrlKey = modifiers.contains(WebEvent::Modifier::ControlKey); 542 bool altKey = modifiers.contains(WebEvent::Modifier::AltKey); 543 bool metaKey = modifiers.contains(WebEvent::Modifier::MetaKey); 544 mainframe.eventHandler().mouseMoved(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap)); 540 545 mainframe.document()->updateStyleIfNeeded(); 541 546 … … 545 550 m_pendingSyntheticClickNode = nullptr; 546 551 m_pendingSyntheticClickLocation = FloatPoint(); 552 m_pendingSyntheticClickModifiers = { }; 547 553 548 554 if (m_isClosed) … … 554 560 LOG(ContentObservation, "handleSyntheticClick: Observed meaningful visible change -> hover."); 555 561 return; 556 case WKContentIndeterminateChange: 562 case WKContentIndeterminateChange: { 557 563 // Wait for callback to completePendingSyntheticClickForContentChangeObserver() to decide whether to send the click event. 558 564 m_pendingSyntheticClickNode = nodeRespondingToClick; 559 565 m_pendingSyntheticClickLocation = location; 566 m_pendingSyntheticClickModifiers = modifiers; 560 567 LOG(ContentObservation, "handleSyntheticClick: Observed some change, but can't decide it yet -> wait."); 561 568 return; 562 case WKContentNoChange:569 } case WKContentNoChange: 563 570 LOG(ContentObservation, "handleSyntheticClick: No change was observed -> click."); 564 completeSyntheticClick(nodeRespondingToClick, location, WebCore::OneFingerTap);571 completeSyntheticClick(nodeRespondingToClick, location, modifiers, WebCore::OneFingerTap); 565 572 return; 566 573 } … … 576 583 if (WKObservedContentChange() == WKContentNoChange) { 577 584 LOG(ContentObservation, "No chage was observed -> click."); 578 completeSyntheticClick(m_pendingSyntheticClickNode.get(), m_pendingSyntheticClickLocation, WebCore::OneFingerTap);585 completeSyntheticClick(m_pendingSyntheticClickNode.get(), m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers, WebCore::OneFingerTap); 579 586 } else 580 587 LOG(ContentObservation, "Observed meaningful visible change -> hover."); … … 582 589 m_pendingSyntheticClickNode = nullptr; 583 590 m_pendingSyntheticClickLocation = FloatPoint(); 584 } 585 586 void WebPage::completeSyntheticClick(Node* nodeRespondingToClick, const WebCore::FloatPoint& location, SyntheticClickType syntheticClickType) 591 m_pendingSyntheticClickModifiers = { }; 592 } 593 594 void WebPage::completeSyntheticClick(Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, SyntheticClickType syntheticClickType) 587 595 { 588 596 IntPoint roundedAdjustedPoint = roundedIntPoint(location); … … 597 605 m_lastInteractionLocation = roundedAdjustedPoint; 598 606 599 tapWasHandled |= mainframe.eventHandler().handleMousePressEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MousePressed, 1, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, syntheticClickType)); 607 // FIXME: Pass caps lock state. 608 bool shiftKey = modifiers.contains(WebEvent::Modifier::ShiftKey); 609 bool ctrlKey = modifiers.contains(WebEvent::Modifier::ControlKey); 610 bool altKey = modifiers.contains(WebEvent::Modifier::AltKey); 611 bool metaKey = modifiers.contains(WebEvent::Modifier::MetaKey); 612 613 tapWasHandled |= mainframe.eventHandler().handleMousePressEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MousePressed, 1, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, syntheticClickType)); 600 614 if (m_isClosed) 601 615 return; 602 616 603 tapWasHandled |= mainframe.eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MouseReleased, 1, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, syntheticClickType));617 tapWasHandled |= mainframe.eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MouseReleased, 1, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, syntheticClickType)); 604 618 if (m_isClosed) 605 619 return; … … 621 635 } 622 636 623 void WebPage::handleTap(const IntPoint& point, uint64_t lastLayerTreeTransactionId)637 void WebPage::handleTap(const IntPoint& point, OptionSet<WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId) 624 638 { 625 639 FloatPoint adjustedPoint; … … 638 652 #endif 639 653 else 640 handleSyntheticClick(nodeRespondingToClick, adjustedPoint );654 handleSyntheticClick(nodeRespondingToClick, adjustedPoint, modifiers); 641 655 } 642 656 … … 733 747 } 734 748 735 void WebPage::handleTwoFingerTapAtPoint(const WebCore::IntPoint& point, uint64_t requestID)749 void WebPage::handleTwoFingerTapAtPoint(const WebCore::IntPoint& point, OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t requestID) 736 750 { 737 751 FloatPoint adjustedPoint; … … 749 763 } else 750 764 #endif 751 completeSyntheticClick(nodeRespondingToClick, adjustedPoint, WebCore::TwoFingerTap);765 completeSyntheticClick(nodeRespondingToClick, adjustedPoint, modifiers, WebCore::TwoFingerTap); 752 766 } 753 767 … … 794 808 } 795 809 796 void WebPage::commitPotentialTap( uint64_t lastLayerTreeTransactionId)810 void WebPage::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId) 797 811 { 798 812 if (!m_potentialTapNode || (!m_potentialTapNode->renderer() && !is<HTMLAreaElement>(m_potentialTapNode.get()))) { … … 818 832 } else 819 833 #endif 820 handleSyntheticClick(nodeRespondingToClick, adjustedPoint );834 handleSyntheticClick(nodeRespondingToClick, adjustedPoint, modifiers); 821 835 } else 822 836 commitPotentialTapFailed(); -
trunk/Tools/ChangeLog
r241278 r241282 1 2019-02-11 Daniel Bates <dabates@apple.com> 2 3 [iOS] Mouse/Touch/Pointer events are missing modifier keys 4 https://bugs.webkit.org/show_bug.cgi?id=191446 5 <rdar://problem/45929460> 6 7 Reviewed by Tim Horton. 8 9 Add support infrastructure for testing touch and stylus taps when holding modifier keys. 10 11 * DumpRenderTree/ios/UIScriptControllerIOS.mm: 12 (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. 13 (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. 14 * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: 15 * TestRunnerShared/UIScriptContext/UIScriptController.cpp: 16 (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. 17 (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. 18 * TestRunnerShared/UIScriptContext/UIScriptController.h: 19 * WebKitTestRunner/ios/UIScriptControllerIOS.mm: 20 (WTR::arrayLength): 21 (WTR::parseModifierArray): 22 (WTR::UIScriptController::singleTapAtPoint): Implemented in terms of singleTapAtPointWithModifiers(). 23 (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. 24 (WTR::UIScriptController::stylusTapAtPoint): Implemented in terms of stylusTapAtPointWithModifiers(). 25 (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. 26 1 27 2019-02-11 Commit Queue <commit-queue@webkit.org> 2 28 -
trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
r241278 r241282 116 116 } 117 117 118 void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback) 119 { 120 } 121 118 122 void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback) 119 123 { … … 141 145 142 146 void UIScriptController::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) 147 { 148 } 149 150 void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback) 143 151 { 144 152 } -
trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
r241278 r241282 57 57 void liftUpAtPoint(long x, long y, long touchCount, object callback); 58 58 void singleTapAtPoint(long x, long y, object callback); 59 void singleTapAtPointWithModifiers(long x, long y, object modifierArray, object callback); 59 60 void doubleTapAtPoint(long x, long y, object callback); 60 61 void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, object callback); … … 66 67 void stylusUpAtPoint(long x, long y, object callback); 67 68 void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object callback); 69 void stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object modifierArray, object callback); 68 70 69 71 void enterText(DOMString text); -
trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
r241278 r241282 266 266 } 267 267 268 void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback) 269 { 270 } 271 268 272 void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef) 269 273 { … … 294 298 } 295 299 300 void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback) 301 { 302 } 303 296 304 void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef callback) 297 305 { -
trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
r241278 r241282 79 79 void liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback); 80 80 void singleTapAtPoint(long x, long y, JSValueRef callback); 81 void singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback); 81 82 void doubleTapAtPoint(long x, long y, JSValueRef callback); 82 83 void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback); … … 86 87 void stylusUpAtPoint(long x, long y, JSValueRef callback); 87 88 void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback); 89 void stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback); 88 90 89 91 void longPressAtPoint(long x, long y, JSValueRef callback); -
trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm
r241278 r241282 64 64 }; 65 65 } 66 67 void UIScriptController::checkForOutstandingCallbacks()68 {69 if (![[HIDEventGenerator sharedHIDEventGenerator] checkForOutstandingCallbacks])70 [NSException raise:@"WebKitTestRunnerTestProblem" format:@"The test completed before all synthesized events had been handled. Perhaps you're calling notifyDone() too early?"];71 }72 73 void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)74 {75 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();76 77 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);78 [webView _doAfterNextPresentationUpdate:^{79 if (!m_context)80 return;81 m_context->asyncTaskComplete(callbackID);82 }];83 }84 85 void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback)86 {87 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();88 89 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);90 [webView _doAfterNextStablePresentationUpdate:^() {91 if (m_context)92 m_context->asyncTaskComplete(callbackID);93 }];94 }95 96 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)97 {98 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();99 100 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);101 [webView _doAfterNextVisibleContentRectUpdate:^ {102 if (!m_context)103 return;104 m_context->asyncTaskComplete(callbackID);105 }];106 }107 108 void UIScriptController::zoomToScale(double scale, JSValueRef callback)109 {110 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();111 112 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);113 114 [webView zoomToScale:scale animated:YES completionHandler:^{115 if (!m_context)116 return;117 m_context->asyncTaskComplete(callbackID);118 }];119 }120 121 void UIScriptController::retrieveSpeakSelectionContent(JSValueRef callback)122 {123 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();124 125 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);126 127 [webView accessibilityRetrieveSpeakSelectionContentWithCompletionHandler:^() {128 if (!m_context)129 return;130 m_context->asyncTaskComplete(callbackID);131 }];132 }133 134 JSRetainPtr<JSStringRef> UIScriptController::accessibilitySpeakSelectionContent() const135 {136 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();137 return JSStringCreateWithCFString((CFStringRef)webView.accessibilitySpeakSelectionContent);138 }139 140 void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)141 {142 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);143 144 auto* webView = TestController::singleton().mainWebView()->platformView();145 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];146 [center postNotificationName:UIAccessibilityInvertColorsStatusDidChangeNotification object:webView];147 148 [webView _doAfterNextPresentationUpdate: ^{149 if (!m_context)150 return;151 m_context->asyncTaskComplete(callbackID);152 }];153 }154 155 double UIScriptController::zoomScale() const156 {157 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();158 return webView.scrollView.zoomScale;159 }160 161 static CGPoint globalToContentCoordinates(TestRunnerWKWebView *webView, long x, long y)162 {163 CGPoint point = CGPointMake(x, y);164 point = [webView _convertPointFromContentsToView:point];165 point = [webView convertPoint:point toView:nil];166 point = [webView.window convertPoint:point toWindow:nil];167 return point;168 }169 170 void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback)171 {172 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);173 174 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);175 [[HIDEventGenerator sharedHIDEventGenerator] touchDown:location touchCount:touchCount completionBlock:^{176 if (!m_context)177 return;178 m_context->asyncTaskComplete(callbackID);179 }];180 }181 182 void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback)183 {184 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);185 186 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);187 [[HIDEventGenerator sharedHIDEventGenerator] liftUp:location touchCount:touchCount completionBlock:^{188 if (!m_context)189 return;190 m_context->asyncTaskComplete(callbackID);191 }];192 }193 194 void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef callback)195 {196 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);197 198 [[HIDEventGenerator sharedHIDEventGenerator] tap:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{199 if (!m_context)200 return;201 m_context->asyncTaskComplete(callbackID);202 }];203 }204 205 void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback)206 {207 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);208 209 [[HIDEventGenerator sharedHIDEventGenerator] doubleTap:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{210 if (!m_context)211 return;212 m_context->asyncTaskComplete(callbackID);213 }];214 }215 216 void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)217 {218 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);219 220 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);221 [[HIDEventGenerator sharedHIDEventGenerator] stylusDownAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{222 if (!m_context)223 return;224 m_context->asyncTaskComplete(callbackID);225 }];226 }227 228 void UIScriptController::stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)229 {230 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);231 232 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);233 [[HIDEventGenerator sharedHIDEventGenerator] stylusMoveToPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{234 if (!m_context)235 return;236 m_context->asyncTaskComplete(callbackID);237 }];238 }239 240 void UIScriptController::stylusUpAtPoint(long x, long y, JSValueRef callback)241 {242 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);243 244 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);245 [[HIDEventGenerator sharedHIDEventGenerator] stylusUpAtPoint:location completionBlock:^{246 if (!m_context)247 return;248 m_context->asyncTaskComplete(callbackID);249 }];250 }251 252 void UIScriptController::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)253 {254 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);255 256 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);257 [[HIDEventGenerator sharedHIDEventGenerator] stylusTapAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{258 if (!m_context)259 return;260 m_context->asyncTaskComplete(callbackID);261 }];262 }263 264 void convertCoordinates(NSMutableDictionary *event)265 {266 if (event[HIDEventTouchesKey]) {267 for (NSMutableDictionary *touch in event[HIDEventTouchesKey]) {268 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), (long)[touch[HIDEventXKey] doubleValue], (long)[touch[HIDEventYKey]doubleValue]);269 touch[HIDEventXKey] = @(location.x);270 touch[HIDEventYKey] = @(location.y);271 }272 }273 }274 275 void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef callback)276 {277 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);278 279 String jsonString = eventsJSON->string();280 auto eventInfo = dynamic_objc_cast<NSDictionary>([NSJSONSerialization JSONObjectWithData:[(NSString *)jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil]);281 282 for (NSMutableDictionary *event in eventInfo[TopLevelEventInfoKey]) {283 if (![event[HIDEventCoordinateSpaceKey] isEqualToString:HIDEventCoordinateSpaceTypeContent])284 continue;285 286 if (event[HIDEventStartEventKey])287 convertCoordinates(event[HIDEventStartEventKey]);288 289 if (event[HIDEventEndEventKey])290 convertCoordinates(event[HIDEventEndEventKey]);291 292 if (event[HIDEventTouchesKey])293 convertCoordinates(event);294 }295 296 if (!eventInfo || ![eventInfo isKindOfClass:[NSDictionary class]]) {297 WTFLogAlways("JSON is not convertible to a dictionary");298 return;299 }300 301 [[HIDEventGenerator sharedHIDEventGenerator] sendEventStream:eventInfo completionBlock:^{302 if (!m_context)303 return;304 m_context->asyncTaskComplete(callbackID);305 }];306 }307 308 void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)309 {310 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);311 312 CGPoint startPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), startX, startY);313 CGPoint endPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), endX, endY);314 315 [[HIDEventGenerator sharedHIDEventGenerator] dragWithStartPoint:startPoint endPoint:endPoint duration:durationSeconds completionBlock:^{316 if (!m_context)317 return;318 m_context->asyncTaskComplete(callbackID);319 }];320 }321 322 void UIScriptController::longPressAtPoint(long x, long y, JSValueRef callback)323 {324 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);325 326 [[HIDEventGenerator sharedHIDEventGenerator] longPress:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{327 if (!m_context)328 return;329 m_context->asyncTaskComplete(callbackID);330 }];331 }332 333 void UIScriptController::enterText(JSStringRef text)334 {335 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();336 auto textAsCFString = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, text));337 [webView _simulateTextEntered:(NSString *)textAsCFString.get()];338 }339 340 void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)341 {342 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);343 344 // Assumes that the keyboard is already shown.345 [[HIDEventGenerator sharedHIDEventGenerator] keyPress:toWTFString(toWK(character)) completionBlock:^{346 if (!m_context)347 return;348 m_context->asyncTaskComplete(callbackID);349 }];350 }351 66 352 67 static unsigned arrayLength(JSContextRef context, JSObjectRef array) … … 388 103 } 389 104 105 void UIScriptController::checkForOutstandingCallbacks() 106 { 107 if (![[HIDEventGenerator sharedHIDEventGenerator] checkForOutstandingCallbacks]) 108 [NSException raise:@"WebKitTestRunnerTestProblem" format:@"The test completed before all synthesized events had been handled. Perhaps you're calling notifyDone() too early?"]; 109 } 110 111 void UIScriptController::doAfterPresentationUpdate(JSValueRef callback) 112 { 113 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 114 115 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 116 [webView _doAfterNextPresentationUpdate:^{ 117 if (!m_context) 118 return; 119 m_context->asyncTaskComplete(callbackID); 120 }]; 121 } 122 123 void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback) 124 { 125 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 126 127 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 128 [webView _doAfterNextStablePresentationUpdate:^() { 129 if (m_context) 130 m_context->asyncTaskComplete(callbackID); 131 }]; 132 } 133 134 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback) 135 { 136 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 137 138 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 139 [webView _doAfterNextVisibleContentRectUpdate:^ { 140 if (!m_context) 141 return; 142 m_context->asyncTaskComplete(callbackID); 143 }]; 144 } 145 146 void UIScriptController::zoomToScale(double scale, JSValueRef callback) 147 { 148 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 149 150 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 151 152 [webView zoomToScale:scale animated:YES completionHandler:^{ 153 if (!m_context) 154 return; 155 m_context->asyncTaskComplete(callbackID); 156 }]; 157 } 158 159 void UIScriptController::retrieveSpeakSelectionContent(JSValueRef callback) 160 { 161 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 162 163 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 164 165 [webView accessibilityRetrieveSpeakSelectionContentWithCompletionHandler:^() { 166 if (!m_context) 167 return; 168 m_context->asyncTaskComplete(callbackID); 169 }]; 170 } 171 172 JSRetainPtr<JSStringRef> UIScriptController::accessibilitySpeakSelectionContent() const 173 { 174 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 175 return JSStringCreateWithCFString((CFStringRef)webView.accessibilitySpeakSelectionContent); 176 } 177 178 void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef callback) 179 { 180 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 181 182 auto* webView = TestController::singleton().mainWebView()->platformView(); 183 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 184 [center postNotificationName:UIAccessibilityInvertColorsStatusDidChangeNotification object:webView]; 185 186 [webView _doAfterNextPresentationUpdate: ^{ 187 if (!m_context) 188 return; 189 m_context->asyncTaskComplete(callbackID); 190 }]; 191 } 192 193 double UIScriptController::zoomScale() const 194 { 195 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 196 return webView.scrollView.zoomScale; 197 } 198 199 static CGPoint globalToContentCoordinates(TestRunnerWKWebView *webView, long x, long y) 200 { 201 CGPoint point = CGPointMake(x, y); 202 point = [webView _convertPointFromContentsToView:point]; 203 point = [webView convertPoint:point toView:nil]; 204 point = [webView.window convertPoint:point toWindow:nil]; 205 return point; 206 } 207 208 void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback) 209 { 210 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 211 212 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 213 [[HIDEventGenerator sharedHIDEventGenerator] touchDown:location touchCount:touchCount completionBlock:^{ 214 if (!m_context) 215 return; 216 m_context->asyncTaskComplete(callbackID); 217 }]; 218 } 219 220 void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback) 221 { 222 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 223 224 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 225 [[HIDEventGenerator sharedHIDEventGenerator] liftUp:location touchCount:touchCount completionBlock:^{ 226 if (!m_context) 227 return; 228 m_context->asyncTaskComplete(callbackID); 229 }]; 230 } 231 232 void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef callback) 233 { 234 singleTapAtPointWithModifiers(x, y, nullptr, callback); 235 } 236 237 void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback) 238 { 239 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 240 241 auto modifierFlags = parseModifierArray(m_context->jsContext(), modifierArray); 242 for (auto& modifierFlag : modifierFlags) 243 [[HIDEventGenerator sharedHIDEventGenerator] keyDown:modifierFlag]; 244 245 [[HIDEventGenerator sharedHIDEventGenerator] tap:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{ 246 if (!m_context) 247 return; 248 for (size_t i = modifierFlags.size(); i; ) { 249 --i; 250 [[HIDEventGenerator sharedHIDEventGenerator] keyUp:modifierFlags[i]]; 251 } 252 [[HIDEventGenerator sharedHIDEventGenerator] sendMarkerHIDEventWithCompletionBlock:^{ 253 if (!m_context) 254 return; 255 m_context->asyncTaskComplete(callbackID); 256 }]; 257 }]; 258 } 259 260 void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback) 261 { 262 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 263 264 [[HIDEventGenerator sharedHIDEventGenerator] doubleTap:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{ 265 if (!m_context) 266 return; 267 m_context->asyncTaskComplete(callbackID); 268 }]; 269 } 270 271 void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) 272 { 273 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 274 275 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 276 [[HIDEventGenerator sharedHIDEventGenerator] stylusDownAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{ 277 if (!m_context) 278 return; 279 m_context->asyncTaskComplete(callbackID); 280 }]; 281 } 282 283 void UIScriptController::stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) 284 { 285 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 286 287 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 288 [[HIDEventGenerator sharedHIDEventGenerator] stylusMoveToPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{ 289 if (!m_context) 290 return; 291 m_context->asyncTaskComplete(callbackID); 292 }]; 293 } 294 295 void UIScriptController::stylusUpAtPoint(long x, long y, JSValueRef callback) 296 { 297 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 298 299 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 300 [[HIDEventGenerator sharedHIDEventGenerator] stylusUpAtPoint:location completionBlock:^{ 301 if (!m_context) 302 return; 303 m_context->asyncTaskComplete(callbackID); 304 }]; 305 } 306 307 void UIScriptController::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) 308 { 309 stylusTapAtPointWithModifiers(x, y, azimuthAngle, altitudeAngle, pressure, nullptr, callback); 310 } 311 312 void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback) 313 { 314 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 315 316 auto modifierFlags = parseModifierArray(m_context->jsContext(), modifierArray); 317 for (auto& modifierFlag : modifierFlags) 318 [[HIDEventGenerator sharedHIDEventGenerator] keyDown:modifierFlag]; 319 320 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 321 [[HIDEventGenerator sharedHIDEventGenerator] stylusTapAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{ 322 if (!m_context) 323 return; 324 for (size_t i = modifierFlags.size(); i; ) { 325 --i; 326 [[HIDEventGenerator sharedHIDEventGenerator] keyUp:modifierFlags[i]]; 327 } 328 [[HIDEventGenerator sharedHIDEventGenerator] sendMarkerHIDEventWithCompletionBlock:^{ 329 if (!m_context) 330 return; 331 m_context->asyncTaskComplete(callbackID); 332 }]; 333 }]; 334 } 335 336 void convertCoordinates(NSMutableDictionary *event) 337 { 338 if (event[HIDEventTouchesKey]) { 339 for (NSMutableDictionary *touch in event[HIDEventTouchesKey]) { 340 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), (long)[touch[HIDEventXKey] doubleValue], (long)[touch[HIDEventYKey]doubleValue]); 341 touch[HIDEventXKey] = @(location.x); 342 touch[HIDEventYKey] = @(location.y); 343 } 344 } 345 } 346 347 void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef callback) 348 { 349 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 350 351 String jsonString = eventsJSON->string(); 352 auto eventInfo = dynamic_objc_cast<NSDictionary>([NSJSONSerialization JSONObjectWithData:[(NSString *)jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil]); 353 354 for (NSMutableDictionary *event in eventInfo[TopLevelEventInfoKey]) { 355 if (![event[HIDEventCoordinateSpaceKey] isEqualToString:HIDEventCoordinateSpaceTypeContent]) 356 continue; 357 358 if (event[HIDEventStartEventKey]) 359 convertCoordinates(event[HIDEventStartEventKey]); 360 361 if (event[HIDEventEndEventKey]) 362 convertCoordinates(event[HIDEventEndEventKey]); 363 364 if (event[HIDEventTouchesKey]) 365 convertCoordinates(event); 366 } 367 368 if (!eventInfo || ![eventInfo isKindOfClass:[NSDictionary class]]) { 369 WTFLogAlways("JSON is not convertible to a dictionary"); 370 return; 371 } 372 373 [[HIDEventGenerator sharedHIDEventGenerator] sendEventStream:eventInfo completionBlock:^{ 374 if (!m_context) 375 return; 376 m_context->asyncTaskComplete(callbackID); 377 }]; 378 } 379 380 void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback) 381 { 382 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 383 384 CGPoint startPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), startX, startY); 385 CGPoint endPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), endX, endY); 386 387 [[HIDEventGenerator sharedHIDEventGenerator] dragWithStartPoint:startPoint endPoint:endPoint duration:durationSeconds completionBlock:^{ 388 if (!m_context) 389 return; 390 m_context->asyncTaskComplete(callbackID); 391 }]; 392 } 393 394 void UIScriptController::longPressAtPoint(long x, long y, JSValueRef callback) 395 { 396 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 397 398 [[HIDEventGenerator sharedHIDEventGenerator] longPress:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{ 399 if (!m_context) 400 return; 401 m_context->asyncTaskComplete(callbackID); 402 }]; 403 } 404 405 void UIScriptController::enterText(JSStringRef text) 406 { 407 TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); 408 auto textAsCFString = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, text)); 409 [webView _simulateTextEntered:(NSString *)textAsCFString.get()]; 410 } 411 412 void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback) 413 { 414 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 415 416 // Assumes that the keyboard is already shown. 417 [[HIDEventGenerator sharedHIDEventGenerator] keyPress:toWTFString(toWK(character)) completionBlock:^{ 418 if (!m_context) 419 return; 420 m_context->asyncTaskComplete(callbackID); 421 }]; 422 } 423 390 424 static UIPhysicalKeyboardEvent *createUIPhysicalKeyboardEvent(NSString *hidInputString, NSString *uiEventInputString, UIKeyModifierFlags modifierFlags, UIKeyboardInputFlags inputFlags, bool isKeyDown) 391 425 {
Note: See TracChangeset
for help on using the changeset viewer.