Changeset 240579 in webkit
- Timestamp:
- Jan 28, 2019 7:08:54 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 19 added
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r240559 r240579 1 2019-01-28 Antoine Quint <graouts@apple.com> 2 3 Limit user-agent interactions based on the touch-action property on iOS 4 https://bugs.webkit.org/show_bug.cgi?id=193447 5 <rdar://problem/47283874> 6 7 Reviewed by Antti Koivisto and Simon Fraser. 8 9 Add a new series of tests that check that the "none", "pan-x", "pan-y" and "pinch-zoom" values have the expected 10 impact on page panning on iOS. 11 12 * pointerevents/ios/touch-action-none-expected.txt: Added. 13 * pointerevents/ios/touch-action-none-in-overflow-scrolling-touch-expected.txt: Added. 14 * pointerevents/ios/touch-action-none-in-overflow-scrolling-touch.html: Added. 15 * pointerevents/ios/touch-action-none-on-iframe-expected.txt: Added. 16 * pointerevents/ios/touch-action-none-on-iframe.html: Added. 17 * pointerevents/ios/touch-action-none-on-parent-expected.txt: Added. 18 * pointerevents/ios/touch-action-none-on-parent.html: Added. 19 * pointerevents/ios/touch-action-none.html: Added. 20 * pointerevents/ios/touch-action-pan-x-expected.txt: Added. 21 * pointerevents/ios/touch-action-pan-x-pan-y-expected.txt: Added. 22 * pointerevents/ios/touch-action-pan-x-pan-y.html: Added. 23 * pointerevents/ios/touch-action-pan-x.html: Added. 24 * pointerevents/ios/touch-action-pan-y-expected.txt: Added. 25 * pointerevents/ios/touch-action-pan-y.html: Added. 26 * pointerevents/ios/touch-action-pinch-zoom-allows-zooming-expected.txt: Added. 27 * pointerevents/ios/touch-action-pinch-zoom-allows-zooming.html: Added. 28 * pointerevents/ios/touch-action-pinch-zoom-prevents-scrolling-expected.txt: Added. 29 * pointerevents/ios/touch-action-pinch-zoom-prevents-scrolling.html: Added. 30 1 31 2019-01-28 Nikita Vasilyev <nvasilyev@apple.com> 2 32 -
trunk/Source/WebCore/ChangeLog
r240558 r240579 1 2019-01-28 Antoine Quint <graouts@apple.com> 2 3 Limit user-agent interactions based on the touch-action property on iOS 4 https://bugs.webkit.org/show_bug.cgi?id=193447 5 <rdar://problem/47283874> 6 7 Reviewed by Antti Koivisto and Simon Fraser. 8 9 We now compile a list of elements with a non-auto touch-action property that is updated whenever an element has its style changed 10 or is removed from its document. When the content of that list changes, we inform the scrolling coordinator such that it can compile 11 a list of TouchActionData structures which hold the touch-action value, the ID of the nearest scroll node and the Region containing 12 the bounds of each of those elements to send it up to the UI process along with touch regions. Computing the list of allowed touch 13 actions for a given element accounts for not only the value specified directly on that element's style, but also in its hierarchy, 14 crossing any frame boundary towards the top-level document's root node. 15 16 Tests: pointerevents/ios/touch-action-none-in-overflow-scrolling-touch.html 17 pointerevents/ios/touch-action-none-on-iframe.html 18 pointerevents/ios/touch-action-none-on-parent.html 19 pointerevents/ios/touch-action-none.html 20 pointerevents/ios/touch-action-pan-x-pan-y.html 21 pointerevents/ios/touch-action-pan-x.html 22 pointerevents/ios/touch-action-pan-y.html 23 pointerevents/ios/touch-action-pinch-zoom-allows-zooming.html 24 pointerevents/ios/touch-action-pinch-zoom-prevents-scrolling.html 25 26 * WebCore.xcodeproj/project.pbxproj: Update how certain headers are exposed such that they can be used from WebKit. 27 * dom/Document.cpp: 28 (WebCore::Document::invalidateRenderingDependentRegions): 29 (WebCore::Document::nodeWillBeRemoved): Ensure a node that is being removed from this document is no longer listed in its 30 list of elements with a non-auto touch-action property. 31 (WebCore::Document::absoluteEventRegionForNode): 32 (WebCore::Document::absoluteRegionForEventTargets): 33 (WebCore::Document::updateTouchActionElements): Create a list of elements with a non-auto touch-action property if one doesn't 34 exist yet and update it to add the given element if it contains a non-auto touch-action, or remove it if it doesn't. If the contents 35 of that list changed as a result, the scrolling coordinator is informed. 36 * dom/Document.h: 37 (WebCore::Document:: const): 38 * dom/Element.cpp: 39 (WebCore::parentCrossingFrameBoundaries): 40 (WebCore::Element::computedTouchActions const): Provide the list of allowed touch actions accounting for the "touch-action" property 41 specified on this element and all of its hierarchy, crossing frame boundary. 42 (WebCore::Element::nearestScrollingNodeIDUsingTouchOverflowScrolling const): Provide the ScrollingNodeID, if any, for the nearest scrolling node 43 for that element. This will allow the UI process to identify which scroll view's behavior to customize to reflect the element's allowed 44 touch actions. 45 * dom/Element.h: 46 * page/scrolling/ScrollingCoordinator.cpp: 47 (WebCore::ScrollingCoordinator::absoluteEventTrackingRegionsForFrame const): Compute the region for all elements with a non-auto touch-action property 48 throughout the provided frame and all of its subframes. 49 * page/scrolling/ScrollingCoordinator.h: 50 (WebCore::ScrollableAreaParameters::operator== const): Deleted. 51 * page/scrolling/ScrollingCoordinatorTypes.h: Added. 52 (WebCore::ScrollableAreaParameters::operator== const): 53 * page/scrolling/ScrollingTree.cpp: 54 (WebCore::ScrollingTree::touchActionDataAtPoint const): Query the list of TouchActionData objects for a match based on the provided point. Right 55 now the logic is pretty crude, stopping at the first TouchActionData for which the region contains the provided point, but future patches will 56 account for overlap and nesting. 57 * page/scrolling/ScrollingTree.h: 58 * page/scrolling/ScrollingTreeNode.h: 59 * platform/EventTrackingRegions.cpp: 60 (WebCore::operator==): 61 * platform/EventTrackingRegions.h: 62 (WebCore::operator!=): 63 * style/StyleTreeResolver.cpp: 64 (WebCore::Style::TreeResolver::resolveElement): Update the list of elements with a non-auto touch-action property when an element's style changes. 65 1 66 2019-01-27 Michael Catanzaro <mcatanzaro@igalia.com> 2 67 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r240552 r240579 2097 2097 712BE4881FE8686A002031CC /* JSFillMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 712BE4851FE86818002031CC /* JSFillMode.h */; }; 2098 2098 712BE4891FE86875002031CC /* JSPlaybackDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 712BE4861FE86859002031CC /* JSPlaybackDirection.h */; }; 2099 712DBA4921F8AD83008F36B2 /* ScrollingCoordinatorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 712DBA4721F8AD79008F36B2 /* ScrollingCoordinatorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2099 2100 713171341FBE78DB00F758DE /* CSSPropertyBlendingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 713171321FBE78C500F758DE /* CSSPropertyBlendingClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2100 2101 7132445120109DA500AE7FB2 /* WebAnimationUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7132444F20109D9B00AE7FB2 /* WebAnimationUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2419 2420 8348BFAC1B85729800912F36 /* ClassCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 8348BFAA1B85729500912F36 /* ClassCollection.h */; }; 2420 2421 834DFAD01F7DAE5D00C2725B /* SharedStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 834DFACC1F7DAE5600C2725B /* SharedStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2421 83520C7E1A71BFCC006BD2AA /* CSSFontFamily.h in Headers */ = {isa = PBXBuildFile; fileRef = 83520C7D1A71BFCC006BD2AA /* CSSFontFamily.h */; };2422 83520C7E1A71BFCC006BD2AA /* CSSFontFamily.h in Headers */ = {isa = PBXBuildFile; fileRef = 83520C7D1A71BFCC006BD2AA /* CSSFontFamily.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2422 2423 8358CB701C53277500E0C2D8 /* JSXMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F570AD1C53268E007FD6CB /* JSXMLDocument.h */; }; 2423 2424 835D2D781F5F1FBD00141DED /* HTMLInputElementEntriesAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 835D2D751F5F1FB800141DED /* HTMLInputElementEntriesAPI.h */; }; … … 2905 2906 996E59DF1DF0128D006612B9 /* NavigatorWebDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 996E59DC1DF00D90006612B9 /* NavigatorWebDriver.h */; }; 2906 2907 9A528E8417D7F52F00AA9518 /* FloatingObjects.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A528E8217D7F52F00AA9518 /* FloatingObjects.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2907 9AB1F38018E2489A00534743 /* CSSToLengthConversionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AB1F37E18E2489A00534743 /* CSSToLengthConversionData.h */; };2908 9AB1F38018E2489A00534743 /* CSSToLengthConversionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AB1F37E18E2489A00534743 /* CSSToLengthConversionData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2908 2909 9B24DE8E15194B9500C59C27 /* HTMLBDIElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B24DE8C15194B9500C59C27 /* HTMLBDIElement.h */; }; 2909 2910 9B2D8A7914997CCF00ECEF3E /* UndoStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B2D8A7814997CCF00ECEF3E /* UndoStep.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 4783 4784 E1E6EEA80B628DB3005F2F70 /* JSHTMLSelectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E6EEA70B628DB3005F2F70 /* JSHTMLSelectElement.h */; }; 4784 4785 E1EC29A00BB04C6B00EA187B /* XPathNodeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EC299E0BB04C6B00EA187B /* XPathNodeSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4785 E1ED8AC30CC49BE000BFC557 /* CSSPrimitiveValueMappings.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ED8AC20CC49BE000BFC557 /* CSSPrimitiveValueMappings.h */; };4786 E1ED8AC30CC49BE000BFC557 /* CSSPrimitiveValueMappings.h in Headers */ = {isa = PBXBuildFile; fileRef = E1ED8AC20CC49BE000BFC557 /* CSSPrimitiveValueMappings.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4786 4787 E1F1E8300C3C2BB9006DB391 /* XSLTExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = E1F1E82E0C3C2BB9006DB391 /* XSLTExtensions.h */; }; 4787 4788 E1F80B8818317252007885C3 /* CryptoKeyPair.h in Headers */ = {isa = PBXBuildFile; fileRef = E1F80B8618317252007885C3 /* CryptoKeyPair.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 9307 9308 712BE4861FE86859002031CC /* JSPlaybackDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPlaybackDirection.h; sourceTree = "<group>"; }; 9308 9309 712BE4871FE8685A002031CC /* JSPlaybackDirection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPlaybackDirection.cpp; sourceTree = "<group>"; }; 9310 712DBA4721F8AD79008F36B2 /* ScrollingCoordinatorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingCoordinatorTypes.h; sourceTree = "<group>"; }; 9309 9311 7130141D1DC9C08600CA3A88 /* pip-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "pip-support.js"; sourceTree = "<group>"; }; 9310 9312 713171321FBE78C500F758DE /* CSSPropertyBlendingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPropertyBlendingClient.h; sourceTree = "<group>"; }; … … 16907 16909 1AF62EE414DA22A70041556C /* ScrollingCoordinator.cpp */, 16908 16910 1AF62EE514DA22A70041556C /* ScrollingCoordinator.h */, 16911 712DBA4721F8AD79008F36B2 /* ScrollingCoordinatorTypes.h */, 16909 16912 51C61B081DE536E7008A212D /* ScrollingMomentumCalculator.cpp */, 16910 16913 51C61B091DE536E7008A212D /* ScrollingMomentumCalculator.h */, … … 29574 29577 089582560E857A7E00F82C83 /* ImageLoader.h in Headers */, 29575 29578 BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */, 29576 A59C230A21F29206004EC939 /* InspectorCPUProfilerAgent.h in Headers */,29577 29579 2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */, 29578 29580 B51A2F3F17D7D3AE0072517A /* ImageQualityController.h in Headers */, … … 29637 29639 1C81B95C0E97330800266E07 /* InspectorClient.h in Headers */, 29638 29640 1C81B95A0E97330800266E07 /* InspectorController.h in Headers */, 29641 A59C230A21F29206004EC939 /* InspectorCPUProfilerAgent.h in Headers */, 29639 29642 A5B81CA91FAA44620037D1E6 /* InspectorCSSAgent.h in Headers */, 29640 29643 4A9CC82116BF9BB400EC645A /* InspectorCSSOMWrappers.h in Headers */, … … 31413 31416 0FC4E40D187F82E10045882C /* ScrollingCoordinatorIOS.h in Headers */, 31414 31417 9391A991162746CB00297330 /* ScrollingCoordinatorMac.h in Headers */, 31418 712DBA4921F8AD83008F36B2 /* ScrollingCoordinatorTypes.h in Headers */, 31415 31419 51C61B0B1DE536E7008A212D /* ScrollingMomentumCalculator.h in Headers */, 31416 31420 517DEEE81DE94B0800B91644 /* ScrollingMomentumCalculatorMac.h in Headers */, -
trunk/Source/WebCore/dom/Document.cpp
r240552 r240579 209 209 #include "TextEvent.h" 210 210 #include "TextNodeTraversal.h" 211 #include "TouchAction.h" 211 212 #include "TransformSource.h" 212 213 #include "TreeWalker.h" … … 4152 4153 setTouchEventRegionsNeedUpdate(); 4153 4154 #endif 4155 4156 #if ENABLE(POINTER_EVENTS) 4157 if (auto* page = this->page()) { 4158 if (auto* frameView = view()) { 4159 if (auto* scrollingCoordinator = page->scrollingCoordinator()) 4160 scrollingCoordinator->frameViewEventTrackingRegionsChanged(*frameView); 4161 } 4162 } 4163 #endif 4154 4164 } 4155 4165 … … 4535 4545 if (is<Text>(node)) 4536 4546 m_markers->removeMarkers(node); 4547 4548 #if ENABLE(POINTER_EVENTS) 4549 if (m_touchActionElements && is<Element>(node)) 4550 m_touchActionElements->remove(&downcast<Element>(node)); 4551 #endif 4537 4552 } 4538 4553 … … 7097 7112 } 7098 7113 7114 Document::RegionFixedPair Document::absoluteEventRegionForNode(Node& node) 7115 { 7116 Region region; 7117 LayoutRect rootRelativeBounds; 7118 bool insideFixedPosition = false; 7119 7120 if (is<Document>(node)) { 7121 auto& document = downcast<Document>(node); 7122 if (&document == this) 7123 rootRelativeBounds = absoluteEventHandlerBounds(insideFixedPosition); 7124 else if (Element* element = document.ownerElement()) 7125 rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition); 7126 } else if (is<Element>(node)) { 7127 auto& element = downcast<Element>(node); 7128 if (is<HTMLBodyElement>(element)) { 7129 // For the body, just use the document bounds. 7130 // The body may not cover this whole area, but it's OK for this region to be an overestimate. 7131 rootRelativeBounds = absoluteEventHandlerBounds(insideFixedPosition); 7132 } else 7133 rootRelativeBounds = element.absoluteEventHandlerBounds(insideFixedPosition); 7134 } 7135 7136 if (!rootRelativeBounds.isEmpty()) 7137 region.unite(Region(enclosingIntRect(rootRelativeBounds))); 7138 7139 return RegionFixedPair(region, insideFixedPosition); 7140 } 7141 7099 7142 Document::RegionFixedPair Document::absoluteRegionForEventTargets(const EventTargetSet* targets) 7100 7143 { … … 7108 7151 7109 7152 for (auto& keyValuePair : *targets) { 7110 LayoutRect rootRelativeBounds; 7111 7112 if (is<Document>(keyValuePair.key)) { 7113 Document* document = downcast<Document>(keyValuePair.key); 7114 if (document == this) 7115 rootRelativeBounds = absoluteEventHandlerBounds(insideFixedPosition); 7116 else if (Element* element = document->ownerElement()) 7117 rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition); 7118 } else if (is<Element>(keyValuePair.key)) { 7119 Element* element = downcast<Element>(keyValuePair.key); 7120 if (is<HTMLBodyElement>(element)) { 7121 // For the body, just use the document bounds. 7122 // The body may not cover this whole area, but it's OK for this region to be an overestimate. 7123 rootRelativeBounds = absoluteEventHandlerBounds(insideFixedPosition); 7124 } else 7125 rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition); 7153 if (auto* node = keyValuePair.key) { 7154 auto targetRegionFixedPair = absoluteEventRegionForNode(*node); 7155 targetRegion.unite(targetRegionFixedPair.first); 7156 insideFixedPosition |= targetRegionFixedPair.second; 7126 7157 } 7127 7128 if (!rootRelativeBounds.isEmpty())7129 targetRegion.unite(Region(enclosingIntRect(rootRelativeBounds)));7130 7158 } 7131 7159 … … 8659 8687 #endif 8660 8688 8689 #if ENABLE(POINTER_EVENTS) 8690 void Document::updateTouchActionElements(Element& element, const RenderStyle& style) 8691 { 8692 bool changed = false; 8693 8694 if (style.touchActions() != TouchAction::Auto) { 8695 if (!m_touchActionElements) 8696 m_touchActionElements = std::make_unique<HashSet<Element*>>(); 8697 changed |= m_touchActionElements->add(&element).isNewEntry; 8698 } else if (m_touchActionElements) 8699 changed |= m_touchActionElements->remove(&element); 8700 8701 #if PLATFORM(IOS_FAMILY) 8702 if (!changed) 8703 return; 8704 8705 Page* page = this->page(); 8706 if (!page) 8707 return; 8708 8709 if (FrameView* frameView = view()) { 8710 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) 8711 scrollingCoordinator->frameViewEventTrackingRegionsChanged(*frameView); 8712 } 8713 #endif 8714 } 8715 #endif 8716 8661 8717 } // namespace WebCore -
trunk/Source/WebCore/dom/Document.h
r240552 r240579 1277 1277 bool touchEventTargetsContain(Node&) const { return false; } 1278 1278 #endif 1279 #if ENABLE(POINTER_EVENTS) 1280 void updateTouchActionElements(Element&, const RenderStyle&); 1281 const HashSet<Element*>* touchActionElements() const { return m_touchActionElements.get(); } 1282 #endif 1279 1283 1280 1284 void didAddTouchEventHandler(Node&); … … 1295 1299 1296 1300 typedef std::pair<Region, bool> RegionFixedPair; 1301 RegionFixedPair absoluteEventRegionForNode(Node&); 1297 1302 RegionFixedPair absoluteRegionForEventTargets(const EventTargetSet*); 1298 1303 … … 1876 1881 std::unique_ptr<EventTargetSet> m_touchEventTargets; 1877 1882 #endif 1883 #if ENABLE(POINTER_EVENTS) 1884 std::unique_ptr<HashSet<Element*>> m_touchActionElements; 1885 #endif 1878 1886 std::unique_ptr<EventTargetSet> m_wheelEventTargets; 1879 1887 -
trunk/Source/WebCore/dom/Element.cpp
r240472 r240579 82 82 #include "RenderFragmentContainer.h" 83 83 #include "RenderLayer.h" 84 #include "RenderLayerBacking.h" 85 #include "RenderLayerCompositor.h" 84 86 #include "RenderListBox.h" 85 87 #include "RenderTheme.h" … … 3419 3421 } 3420 3422 3421 static Element* parentCrossingFrameBoundaries( Element* element)3423 static Element* parentCrossingFrameBoundaries(const Element* element) 3422 3424 { 3423 3425 ASSERT(element); … … 4123 4125 #endif 4124 4126 4127 #if ENABLE(POINTER_EVENTS) 4128 OptionSet<TouchAction> Element::computedTouchActions() const 4129 { 4130 OptionSet<TouchAction> computedTouchActions = TouchAction::Auto; 4131 for (auto* element = this; element; element = parentCrossingFrameBoundaries(element)) { 4132 auto* renderer = element->renderer(); 4133 if (!renderer) 4134 continue; 4135 4136 auto touchActions = renderer->style().touchActions(); 4137 4138 // Once we've encountered touch-action: none, we know that this will be the computed value. 4139 if (touchActions == TouchAction::None) 4140 return touchActions; 4141 4142 // If the computed touch-action so far was "auto", we can just use the current element's touch-action. 4143 if (computedTouchActions == TouchAction::Auto) { 4144 computedTouchActions = touchActions; 4145 continue; 4146 } 4147 4148 // If the current element has touch-action: auto or the same touch-action as the computed touch-action, 4149 // we need to keep going up the ancestry chain. 4150 if (touchActions == TouchAction::Auto || touchActions == computedTouchActions) 4151 continue; 4152 4153 // Now, the element's touch-action and the computed touch-action are different and are neither "auto" nor "none". 4154 if (computedTouchActions == TouchAction::Manipulation) { 4155 // If the computed touch-action is "manipulation", we can take the current element's touch-action as the newly 4156 // computed touch-action. 4157 computedTouchActions = touchActions; 4158 } else if (touchActions == TouchAction::Manipulation) { 4159 // Otherwise, we have a restricted computed touch-action so far. If the current element's touch-action is "manipulation" 4160 // then we can just keep going and leave the computed touch-action untouched. 4161 continue; 4162 } 4163 4164 // In any other case, we have competing restrictive touch-action values that can only yield "none". 4165 return TouchAction::None; 4166 } 4167 return computedTouchActions; 4168 } 4169 4170 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) 4171 ScrollingNodeID Element::nearestScrollingNodeIDUsingTouchOverflowScrolling() const 4172 { 4173 if (!renderer()) 4174 return 0; 4175 4176 // We are not interested in the root, so check that we also have a valid parent. 4177 for (auto* layer = renderer()->enclosingLayer(); layer && layer->parent(); layer = layer->parent()) { 4178 if (layer->isComposited()) { 4179 if (auto scrollingNodeID = layer->backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling)) 4180 return scrollingNodeID; 4181 } 4182 } 4183 4184 return 0; 4185 } 4186 #endif 4187 #endif 4188 4125 4189 } // namespace WebCore -
trunk/Source/WebCore/dom/Element.h
r240237 r240579 32 32 #include "ScrollToOptions.h" 33 33 #include "ScrollTypes.h" 34 #include "ScrollingCoordinator.h" 34 35 #include "ShadowRootMode.h" 35 36 #include "SimulatedClickOptions.h" … … 76 77 }; 77 78 79 #if ENABLE(POINTER_EVENTS) 80 enum class TouchAction : uint8_t; 81 #endif 82 78 83 class Element : public ContainerNode { 79 84 WTF_MAKE_ISO_ALLOCATED(Element); … … 589 594 Vector<RefPtr<WebAnimation>> getAnimations(); 590 595 596 #if ENABLE(POINTER_EVENTS) 597 OptionSet<TouchAction> computedTouchActions() const; 598 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) 599 ScrollingNodeID nearestScrollingNodeIDUsingTouchOverflowScrolling() const; 600 #endif 601 #endif 602 591 603 protected: 592 604 Element(const QualifiedName&, Document&, ConstructionType); -
trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
r240435 r240579 39 39 #include "RenderLayerCompositor.h" 40 40 #include "RenderView.h" 41 #include "RuntimeEnabledFeatures.h" 41 42 #include "ScrollAnimator.h" 42 43 #include "Settings.h" … … 108 109 if (!document) 109 110 return EventTrackingRegions(); 110 return document->eventTrackingRegions(); 111 auto eventTrackingRegions = document->eventTrackingRegions(); 112 113 #if ENABLE(POINTER_EVENTS) 114 if (RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled()) { 115 if (auto* touchActionElements = frame.document()->touchActionElements()) { 116 auto& touchActionData = eventTrackingRegions.touchActionData; 117 for (const auto& element : *touchActionElements) { 118 ASSERT(element); 119 touchActionData.append({ 120 element->computedTouchActions(), 121 element->nearestScrollingNodeIDUsingTouchOverflowScrolling(), 122 element->document().absoluteEventRegionForNode(*element).first 123 }); 124 } 125 } 126 } 127 #endif 128 129 return eventTrackingRegions; 111 130 #else 112 131 auto* frameView = frame.view(); -
trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h
r240551 r240579 31 31 #include "ScrollSnapOffsetsInfo.h" 32 32 #include "ScrollTypes.h" 33 #include "ScrollingCoordinatorTypes.h" 33 34 #include <wtf/Forward.h> 34 35 #include <wtf/ThreadSafeRefCounted.h> … … 51 52 52 53 namespace WebCore { 53 54 typedef unsigned SynchronousScrollingReasons;55 typedef uint64_t ScrollingNodeID;56 57 enum class ScrollingNodeType : uint8_t {58 MainFrame,59 Subframe,60 FrameHosting,61 Overflow,62 Fixed,63 Sticky64 };65 66 enum ScrollingStateTreeAsTextBehaviorFlags {67 ScrollingStateTreeAsTextBehaviorNormal = 0,68 ScrollingStateTreeAsTextBehaviorIncludeLayerIDs = 1 << 0,69 ScrollingStateTreeAsTextBehaviorIncludeNodeIDs = 1 << 1,70 ScrollingStateTreeAsTextBehaviorIncludeLayerPositions = 1 << 2,71 ScrollingStateTreeAsTextBehaviorDebug = ScrollingStateTreeAsTextBehaviorIncludeLayerIDs | ScrollingStateTreeAsTextBehaviorIncludeNodeIDs | ScrollingStateTreeAsTextBehaviorIncludeLayerPositions72 };73 typedef unsigned ScrollingStateTreeAsTextBehavior;74 54 75 55 class Document; … … 86 66 class ScrollingTree; 87 67 #endif 88 89 enum class ScrollingLayerPositionAction {90 Set,91 SetApproximate,92 Sync93 };94 95 struct ScrollableAreaParameters {96 ScrollElasticity horizontalScrollElasticity { ScrollElasticityNone };97 ScrollElasticity verticalScrollElasticity { ScrollElasticityNone };98 99 ScrollbarMode horizontalScrollbarMode { ScrollbarAuto };100 ScrollbarMode verticalScrollbarMode { ScrollbarAuto };101 102 bool hasEnabledHorizontalScrollbar { false };103 bool hasEnabledVerticalScrollbar { false };104 105 bool useDarkAppearanceForScrollbars { false };106 107 bool operator==(const ScrollableAreaParameters& other) const108 {109 return horizontalScrollElasticity == other.horizontalScrollElasticity110 && verticalScrollElasticity == other.verticalScrollElasticity111 && horizontalScrollbarMode == other.horizontalScrollbarMode112 && verticalScrollbarMode == other.verticalScrollbarMode113 && hasEnabledHorizontalScrollbar == other.hasEnabledHorizontalScrollbar114 && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar115 && useDarkAppearanceForScrollbars == other.useDarkAppearanceForScrollbars;116 }117 };118 119 enum class ViewportRectStability {120 Stable,121 Unstable,122 ChangingObscuredInsetsInteractively // This implies Unstable.123 };124 68 125 69 class ScrollingCoordinator : public ThreadSafeRefCounted<ScrollingCoordinator> { -
trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp
r239427 r240579 404 404 } 405 405 406 #if ENABLE(POINTER_EVENTS) 407 Optional<TouchActionData> ScrollingTree::touchActionDataAtPoint(IntPoint p) const 408 { 409 // FIXME: This does not handle the case where there are multiple regions matching this point. 410 for (auto& touchActionData : m_eventTrackingRegions.touchActionData) { 411 if (touchActionData.region.contains(p)) 412 return touchActionData; 413 } 414 415 return WTF::nullopt; 416 } 417 #endif 418 406 419 } // namespace WebCore 407 420 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.h
r239427 r240579 31 31 #include "Region.h" 32 32 #include "ScrollingCoordinator.h" 33 #include "TouchAction.h" 33 34 #include "WheelEventTestTrigger.h" 34 35 #include <wtf/HashMap.h> … … 105 106 106 107 WEBCORE_EXPORT TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint); 107 108 #if ENABLE(POINTER_EVENTS) 109 WEBCORE_EXPORT Optional<TouchActionData> touchActionDataAtPoint(IntPoint) const; 110 #endif 111 108 112 #if PLATFORM(MAC) 109 113 virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0; -
trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h
r240435 r240579 32 32 #include "ScrollingCoordinator.h" 33 33 #include "ScrollingStateNode.h" 34 #include "TouchAction.h" 34 35 #include <wtf/RefCounted.h> 35 36 #include <wtf/TypeCasts.h> -
trunk/Source/WebCore/platform/EventTrackingRegions.cpp
r202408 r240579 74 74 { 75 75 return a.asynchronousDispatchRegion == b.asynchronousDispatchRegion 76 #if ENABLE(POINTER_EVENTS) 77 && a.touchActionData == b.touchActionData 78 #endif 76 79 && a.eventSpecificSynchronousDispatchRegions == b.eventSpecificSynchronousDispatchRegions; 77 80 } 78 81 82 #if ENABLE(POINTER_EVENTS) 83 bool operator==(const TouchActionData& a, const TouchActionData& b) 84 { 85 return a.touchActions == b.touchActions 86 && a.scrollingNodeID == b.scrollingNodeID 87 && a.region == b.region; 88 } 89 #endif 90 79 91 } // namespace WebCore -
trunk/Source/WebCore/platform/EventTrackingRegions.h
r202408 r240579 31 31 #include <wtf/text/WTFString.h> 32 32 33 #if ENABLE(POINTER_EVENTS) 34 #include "CSSPrimitiveValueMappings.h" 35 #include "ScrollingCoordinatorTypes.h" 36 #include "TouchAction.h" 37 #endif 38 33 39 namespace WebCore { 34 40 … … 39 45 }; 40 46 47 #if ENABLE(POINTER_EVENTS) 48 typedef uint64_t ScrollingNodeID; 49 struct TouchActionData { 50 OptionSet<TouchAction> touchActions { TouchAction::Auto }; 51 ScrollingNodeID scrollingNodeID { 0 }; 52 Region region; 53 }; 54 55 bool operator==(const TouchActionData&, const TouchActionData&); 56 inline bool operator!=(const TouchActionData& a, const TouchActionData& b) { return !(a == b); } 57 #endif 58 41 59 struct EventTrackingRegions { 42 60 // Region for which events can be dispatched without blocking scrolling. … … 46 64 // The key is the Event Name with an active handler. 47 65 HashMap<String, Region> eventSpecificSynchronousDispatchRegions; 66 67 #if ENABLE(POINTER_EVENTS) 68 Vector<TouchActionData> touchActionData; 69 #endif 48 70 49 71 bool isEmpty() const; -
trunk/Source/WebCore/style/StyleTreeResolver.cpp
r240037 r240579 237 237 auto afterUpdate = resolvePseudoStyle(element, update, PseudoId::After); 238 238 239 #if ENABLE(POINTER_EVENTS) 240 if (RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled()) 241 m_document.updateTouchActionElements(element, *update.style.get()); 242 #endif 243 239 244 return { WTFMove(update), descendantsToResolve, WTFMove(beforeUpdate), WTFMove(afterUpdate) }; 240 245 } -
trunk/Source/WebKit/ChangeLog
r240578 r240579 1 2019-01-28 Antoine Quint <graouts@apple.com> 2 3 Limit user-agent interactions based on the touch-action property on iOS 4 https://bugs.webkit.org/show_bug.cgi?id=193447 5 <rdar://problem/47283874> 6 7 Reviewed by Antti Koivisto and Simon Fraser. 8 9 Handle the "none", "pan-x", "pan-y" and "pinch-zoom" values for the touch-action property by querying the scrolling tree whenever a touch begins 10 to identify whether its point is contained within the region of an element with a non-auto touch-action property. If it is, we use the list of 11 permitted touch actions such to then customize the behavior of the nearest scroll view to pan or zoom only as instructed. 12 13 * Shared/WebCoreArgumentCoders.cpp: 14 (IPC::ArgumentCoder<TouchActionData>::encode): 15 (IPC::ArgumentCoder<TouchActionData>::decode): 16 (IPC::ArgumentCoder<EventTrackingRegions>::encode): 17 (IPC::ArgumentCoder<EventTrackingRegions>::decode): 18 (IPC::ArgumentCoder<Region>::decode): 19 * Shared/WebCoreArgumentCoders.h: 20 * UIProcess/API/Cocoa/WKWebView.mm: 21 (-[WKWebView scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Account for panning constraints set on the content view to prevent deceleration 22 to pan the view if it ought not. 23 (-[WKWebView _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Implement an additional 24 UIScrollView delegation method to apply the panning constraints set on the content view while panning. 25 * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp: 26 (WebKit::RemoteScrollingCoordinatorProxy::touchActionDataAtPoint const): 27 (WebKit::RemoteScrollingCoordinatorProxy::touchActionDataForScrollNodeID const): 28 (WebKit::RemoteScrollingCoordinatorProxy::setTouchDataForTouchIdentifier): 29 (WebKit::RemoteScrollingCoordinatorProxy::clearTouchDataForTouchIdentifier): 30 * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h: 31 * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: 32 * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: 33 (-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Apply the same logic as in WKWebView. 34 (-[WKScrollingNodeScrollViewDelegate _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Apply 35 the same logic as in WKWebView. 36 (WebKit::ScrollingTreeScrollingNodeDelegateIOS::touchActionData const): 37 * UIProcess/WebPageProxy.h: 38 (WebKit::WebPageProxy::isScrollingOrZooming const): 39 * UIProcess/ios/WKContentViewInteraction.h: 40 * UIProcess/ios/WKContentViewInteraction.mm: 41 (-[WKContentView preventsPanningInXAxis]): 42 (-[WKContentView preventsPanningInYAxis]): 43 (-[WKContentView cleanupInteraction]): 44 (-[WKContentView _webTouchEventsRecognized:]): 45 (-[WKContentView _handleTouchActionsForTouchEvent:]): As we process touches, check whether there are touch actions set for this touch's points' locations. Based 46 on those touch actions, either setDefaultPrevented on the _touchEventGestureRecognizer if the touch action is "none" or selectively disable panning and zooming. 47 (-[WKContentView _resetPanningPreventionFlags]): 48 (-[WKContentView _didEndScrollingOrZooming]): 49 1 50 2019-01-28 Antti Koivisto <antti@apple.com> 2 51 -
trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp
r239888 r240579 330 330 } 331 331 332 #if ENABLE(POINTER_EVENTS) 333 void ArgumentCoder<TouchActionData>::encode(Encoder& encoder, const TouchActionData& touchActionData) 334 { 335 encoder << touchActionData.touchActions << touchActionData.scrollingNodeID << touchActionData.region; 336 } 337 338 Optional<TouchActionData> ArgumentCoder<TouchActionData>::decode(Decoder& decoder) 339 { 340 Optional<OptionSet<TouchAction>> touchActions; 341 decoder >> touchActions; 342 if (!touchActions) 343 return WTF::nullopt; 344 345 Optional<ScrollingNodeID> scrollingNodeID; 346 decoder >> scrollingNodeID; 347 if (!scrollingNodeID) 348 return WTF::nullopt; 349 350 Optional<Region> region; 351 decoder >> region; 352 if (!region) 353 return WTF::nullopt; 354 355 return {{ WTFMove(*touchActions), WTFMove(*scrollingNodeID), WTFMove(*region) }}; 356 } 357 #endif 358 332 359 void ArgumentCoder<EventTrackingRegions>::encode(Encoder& encoder, const EventTrackingRegions& eventTrackingRegions) 333 360 { 334 361 encoder << eventTrackingRegions.asynchronousDispatchRegion; 335 362 encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions; 363 #if ENABLE(POINTER_EVENTS) 364 encoder << eventTrackingRegions.touchActionData; 365 #endif 336 366 } 337 367 … … 344 374 if (!decoder.decode(eventSpecificSynchronousDispatchRegions)) 345 375 return false; 376 #if ENABLE(POINTER_EVENTS) 377 Vector<TouchActionData> touchActionData; 378 if (!decoder.decode(touchActionData)) 379 return false; 380 #endif 346 381 eventTrackingRegions.asynchronousDispatchRegion = WTFMove(asynchronousDispatchRegion); 347 382 eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions); 383 #if ENABLE(POINTER_EVENTS) 384 eventTrackingRegions.touchActionData = WTFMove(touchActionData); 385 #endif 348 386 return true; 349 387 } … … 914 952 915 953 return true; 954 } 955 956 Optional<Region> ArgumentCoder<Region>::decode(Decoder& decoder) 957 { 958 Region region; 959 if (!decode(decoder, region)) 960 return WTF::nullopt; 961 962 return region; 916 963 } 917 964 -
trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h
r240199 r240579 122 122 struct TextCheckingResult; 123 123 struct TextIndicatorData; 124 #if ENABLE(POINTER_EVENTS) 125 struct TouchActionData; 126 #endif 124 127 struct ViewportAttributes; 125 128 struct WindowFeatures; … … 200 203 }; 201 204 205 #if ENABLE(POINTER_EVENTS) 206 template<> struct ArgumentCoder<WebCore::TouchActionData> { 207 static void encode(Encoder&, const WebCore::TouchActionData&); 208 static Optional<WebCore::TouchActionData> decode(Decoder&); 209 }; 210 #endif 211 202 212 template<> struct ArgumentCoder<WebCore::EventTrackingRegions> { 203 213 static void encode(Encoder&, const WebCore::EventTrackingRegions&); … … 317 327 static void encode(Encoder&, const WebCore::Region&); 318 328 static bool decode(Decoder&, WebCore::Region&); 329 static Optional<WebCore::Region> decode(Decoder&); 319 330 }; 320 331 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r240490 r240579 2584 2584 if ([scrollView isZooming]) 2585 2585 *targetContentOffset = [scrollView contentOffset]; 2586 #if ENABLE(POINTER_EVENTS) 2587 else { 2588 if ([_contentView preventsPanningInXAxis]) 2589 targetContentOffset->x = scrollView.contentOffset.x; 2590 if ([_contentView preventsPanningInYAxis]) 2591 targetContentOffset->y = scrollView.contentOffset.y; 2592 } 2593 #endif 2586 2594 #if ENABLE(CSS_SCROLL_SNAP) && ENABLE(ASYNC_SCROLLING) 2587 2595 if (WebKit::RemoteScrollingCoordinatorProxy* coordinator = _page->scrollingCoordinatorProxy()) { … … 2619 2627 { 2620 2628 [self _didFinishScrolling]; 2629 } 2630 2631 - (CGPoint)_scrollView:(UIScrollView *)scrollView adjustedOffsetForOffset:(CGPoint)offset translation:(CGPoint)translation startPoint:(CGPoint)start locationInView:(CGPoint)locationInView horizontalVelocity:(inout double *)hv verticalVelocity:(inout double *)vv 2632 { 2633 if (![_contentView preventsPanningInXAxis] && ![_contentView preventsPanningInYAxis]) 2634 return offset; 2635 2636 CGPoint adjustedContentOffset = CGPointMake(offset.x, offset.y); 2637 if ([_contentView preventsPanningInXAxis]) 2638 adjustedContentOffset.x = start.x; 2639 if ([_contentView preventsPanningInYAxis]) 2640 adjustedContentOffset.y = start.y; 2641 2642 return adjustedContentOffset; 2621 2643 } 2622 2644 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
r240435 r240579 207 207 } 208 208 209 #if ENABLE(POINTER_EVENTS) 210 Optional<TouchActionData> RemoteScrollingCoordinatorProxy::touchActionDataAtPoint(const IntPoint p) const 211 { 212 return m_scrollingTree->touchActionDataAtPoint(p); 213 } 214 215 Optional<TouchActionData> RemoteScrollingCoordinatorProxy::touchActionDataForScrollNodeID(ScrollingNodeID scrollingNodeID) const 216 { 217 for (auto& touchActionData : m_touchActionDataByTouchIdentifier.values()) { 218 if (touchActionData.scrollingNodeID == scrollingNodeID) 219 return touchActionData; 220 } 221 return WTF::nullopt; 222 } 223 224 void RemoteScrollingCoordinatorProxy::setTouchDataForTouchIdentifier(TouchActionData touchActionData, unsigned touchIdentifier) 225 { 226 m_touchActionDataByTouchIdentifier.set(touchIdentifier, touchActionData); 227 } 228 229 void RemoteScrollingCoordinatorProxy::clearTouchDataForTouchIdentifier(unsigned touchIdentifier) 230 { 231 m_touchActionDataByTouchIdentifier.remove(touchIdentifier); 232 } 233 234 #endif 235 209 236 } // namespace WebKit 210 237 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h
r239689 r240579 99 99 String scrollingTreeAsText() const; 100 100 101 #if ENABLE(POINTER_EVENTS) 102 Optional<WebCore::TouchActionData> touchActionDataAtPoint(const WebCore::IntPoint) const; 103 Optional<WebCore::TouchActionData> touchActionDataForScrollNodeID(WebCore::ScrollingNodeID) const; 104 void setTouchDataForTouchIdentifier(WebCore::TouchActionData, unsigned); 105 void clearTouchDataForTouchIdentifier(unsigned); 106 #endif 107 101 108 private: 102 109 void connectStateNodeLayers(WebCore::ScrollingStateTree&, const RemoteLayerTreeHost&); … … 108 115 WebPageProxy& m_webPageProxy; 109 116 RefPtr<RemoteScrollingTree> m_scrollingTree; 117 #if ENABLE(POINTER_EVENTS) 118 HashMap<unsigned, WebCore::TouchActionData> m_touchActionDataByTouchIdentifier; 119 #endif 110 120 RequestedScrollInfo* m_requestedScrollInfo; 111 121 #if ENABLE(CSS_SCROLL_SNAP) -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h
r237266 r240579 66 66 void setScrollLayerPosition(const WebCore::FloatPoint&); 67 67 void updateChildNodesAfterScroll(const WebCore::FloatPoint& scrollPosition); 68 #if ENABLE(POINTER_EVENTS) 69 Optional<TouchActionData> touchActionData() const; 70 #endif 68 71 69 72 private: -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm
r239548 r240579 68 68 } 69 69 70 - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 71 { 72 #if ENABLE(POINTER_EVENTS) 73 if (![scrollView isZooming]) { 74 if (auto touchActionData = _scrollingTreeNodeDelegate->touchActionData()) { 75 auto touchActions = touchActionData->touchActions; 76 if (touchActions != WebCore::TouchAction::Auto && touchActions != WebCore::TouchAction::Manipulation) { 77 bool canPanX = true; 78 bool canPanY = true; 79 if (!touchActions.contains(WebCore::TouchAction::PanX)) { 80 canPanX = false; 81 targetContentOffset->x = scrollView.contentOffset.x; 82 } 83 if (!touchActions.contains(WebCore::TouchAction::PanY)) { 84 canPanY = false; 85 targetContentOffset->y = scrollView.contentOffset.y; 86 } 87 } 88 } 89 } 90 #endif 91 70 92 #if ENABLE(CSS_SCROLL_SNAP) 71 - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset72 {73 93 CGFloat horizontalTarget = targetContentOffset->x; 74 94 CGFloat verticalTarget = targetContentOffset->y; … … 97 117 _scrollingTreeNodeDelegate->currentSnapPointIndicesDidChange(_scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex(), _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex()); 98 118 } 99 } 100 #endif 119 #endif 120 } 101 121 102 122 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)willDecelerate … … 117 137 } 118 138 } 139 140 #if ENABLE(POINTER_EVENTS) 141 - (CGPoint)_scrollView:(UIScrollView *)scrollView adjustedOffsetForOffset:(CGPoint)offset translation:(CGPoint)translation startPoint:(CGPoint)start locationInView:(CGPoint)locationInView horizontalVelocity:(inout double *)hv verticalVelocity:(inout double *)vv 142 { 143 auto touchActionData = _scrollingTreeNodeDelegate->touchActionData(); 144 if (!touchActionData) 145 return offset; 146 147 auto touchActions = touchActionData->touchActions; 148 if (touchActions == WebCore::TouchAction::Auto || touchActions == WebCore::TouchAction::Manipulation) 149 return offset; 150 151 CGPoint adjustedContentOffset = CGPointMake(offset.x, offset.y); 152 153 if (!touchActions.contains(WebCore::TouchAction::PanX)) 154 adjustedContentOffset.x = start.x; 155 if (!touchActions.contains(WebCore::TouchAction::PanY)) 156 adjustedContentOffset.y = start.y; 157 158 return adjustedContentOffset; 159 } 160 #endif 119 161 120 162 @end … … 288 330 } 289 331 332 #if ENABLE(POINTER_EVENTS) 333 Optional<TouchActionData> ScrollingTreeScrollingNodeDelegateIOS::touchActionData() const 334 { 335 return downcast<RemoteScrollingTree>(scrollingTree()).scrollingCoordinatorProxy().touchActionDataForScrollNodeID(scrollingNode().scrollingNodeID()); 336 } 337 #endif 338 290 339 } // namespace WebKit 291 340 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r240491 r240579 679 679 void cancelAutoscroll(); 680 680 void hardwareKeyboardAvailabilityChanged(); 681 bool isScrollingOrZooming() const { return m_isScrollingOrZooming; } 681 682 #if ENABLE(DATA_INTERACTION) 682 683 void didHandleDragStartRequest(bool started); -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r240491 r240579 197 197 198 198 BOOL _canSendTouchEventsAsynchronously; 199 #if ENABLE(POINTER_EVENTS) 200 BOOL _preventsPanningInXAxis; 201 BOOL _preventsPanningInYAxis; 202 #endif 199 203 200 204 RetainPtr<WKSyntheticClickTapGestureRecognizer> _singleTapGestureRecognizer; … … 350 354 @property (nonatomic, readonly) UIWebFormAccessory *formAccessoryView; 351 355 @property (nonatomic, readonly) UITextInputAssistantItem *inputAssistantItemForWebView; 356 #if ENABLE(POINTER_EVENTS) 357 @property (nonatomic, readonly) BOOL preventsPanningInXAxis; 358 @property (nonatomic, readonly) BOOL preventsPanningInYAxis; 359 #endif 352 360 353 361 #if ENABLE(DATALIST_ELEMENT) -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r240514 r240579 130 130 #endif 131 131 132 #if ENABLE(POINTER_EVENTS) 133 #import "RemoteScrollingCoordinatorProxy.h" 134 #import <WebCore/TouchAction.h> 135 #endif 136 132 137 #if PLATFORM(WATCHOS) 133 138 … … 609 614 } 610 615 616 #if ENABLE(POINTER_EVENTS) 617 - (BOOL)preventsPanningInXAxis 618 { 619 return _preventsPanningInXAxis; 620 } 621 622 - (BOOL)preventsPanningInYAxis 623 { 624 return _preventsPanningInYAxis; 625 } 626 #endif 627 611 628 - (WKFormInputSession *)_formInputSession 612 629 { … … 855 872 _suppressSelectionAssistantReasons = { }; 856 873 _isZoomingToRevealFocusedElement = NO; 874 875 #if ENABLE(POINTER_EVENTS) 876 [self _resetPanningPreventionFlags]; 877 #endif 857 878 } 858 879 … … 1122 1143 nativeWebTouchEvent.setCanPreventNativeGestures(!_canSendTouchEventsAsynchronously || [gestureRecognizer isDefaultPrevented]); 1123 1144 1145 #if ENABLE(POINTER_EVENTS) 1146 [self _handleTouchActionsForTouchEvent:nativeWebTouchEvent]; 1147 #endif 1148 1124 1149 if (_canSendTouchEventsAsynchronously) 1125 1150 _page->handleTouchEventAsynchronously(nativeWebTouchEvent); … … 1127 1152 _page->handleTouchEventSynchronously(nativeWebTouchEvent); 1128 1153 1129 if (nativeWebTouchEvent.allTouchPointsAreReleased()) 1154 if (nativeWebTouchEvent.allTouchPointsAreReleased()) { 1130 1155 _canSendTouchEventsAsynchronously = NO; 1131 #endif 1132 } 1156 1157 #if ENABLE(POINTER_EVENTS) 1158 if (!_page->isScrollingOrZooming()) 1159 [self _resetPanningPreventionFlags]; 1160 #endif 1161 } 1162 #endif 1163 } 1164 1165 #if ENABLE(POINTER_EVENTS) 1166 - (void)_handleTouchActionsForTouchEvent:(const WebKit::NativeWebTouchEvent&)touchEvent 1167 { 1168 auto* scrollingCoordinator = _page->scrollingCoordinatorProxy(); 1169 if (!scrollingCoordinator) 1170 return; 1171 1172 for (const auto& touchPoint : touchEvent.touchPoints()) { 1173 auto phase = touchPoint.phase(); 1174 if (phase == WebKit::WebPlatformTouchPoint::TouchPressed) { 1175 auto touchActionData = scrollingCoordinator->touchActionDataAtPoint(touchPoint.location()); 1176 if (!touchActionData) 1177 continue; 1178 if (touchActionData->touchActions == WebCore::TouchAction::None) 1179 [_touchEventGestureRecognizer setDefaultPrevented:YES]; 1180 else if (!touchActionData->touchActions.contains(WebCore::TouchAction::Manipulation)) { 1181 if (auto scrollingNodeID = touchActionData->scrollingNodeID) 1182 scrollingCoordinator->setTouchDataForTouchIdentifier(*touchActionData, touchPoint.identifier()); 1183 else { 1184 if (!touchActionData->touchActions.contains(WebCore::TouchAction::PinchZoom)) 1185 _webView.scrollView.pinchGestureRecognizer.enabled = NO; 1186 _preventsPanningInXAxis = !touchActionData->touchActions.contains(WebCore::TouchAction::PanX); 1187 _preventsPanningInYAxis = !touchActionData->touchActions.contains(WebCore::TouchAction::PanY); 1188 } 1189 } 1190 } else if (phase == WebKit::WebPlatformTouchPoint::TouchReleased || phase == WebKit::WebPlatformTouchPoint::TouchCancelled) 1191 scrollingCoordinator->clearTouchDataForTouchIdentifier(touchPoint.identifier()); 1192 } 1193 } 1194 1195 - (void)_resetPanningPreventionFlags 1196 { 1197 _preventsPanningInXAxis = NO; 1198 _preventsPanningInYAxis = NO; 1199 } 1200 #endif 1133 1201 1134 1202 - (void)_inspectorNodeSearchRecognized:(UIGestureRecognizer *)gestureRecognizer … … 2192 2260 } 2193 2261 _page->setIsScrollingOrZooming(false); 2262 2263 #if ENABLE(POINTER_EVENTS) 2264 [self _resetPanningPreventionFlags]; 2265 #endif 2194 2266 2195 2267 #if PLATFORM(WATCHOS)
Note: See TracChangeset
for help on using the changeset viewer.