1/*
2 * Copyright (C) 2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(POINTER_EVENTS)
29
30#include "EventNames.h"
31#include "MouseEvent.h"
32#include "Node.h"
33#include "PointerID.h"
34#include <wtf/text/WTFString.h>
35
36#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
37#include "PlatformTouchEventIOS.h"
38#endif
39
40namespace WebCore {
41
42class PointerEvent final : public MouseEvent {
43public:
44 struct Init : MouseEventInit {
45 PointerID pointerId { mousePointerID };
46 double width { 1 };
47 double height { 1 };
48 float pressure { 0 };
49 float tangentialPressure { 0 };
50 long tiltX { 0 };
51 long tiltY { 0 };
52 long twist { 0 };
53 String pointerType { PointerEvent::mousePointerType() };
54 bool isPrimary { false };
55 };
56
57 enum class IsPrimary : uint8_t { No, Yes };
58
59 static Ref<PointerEvent> create(const AtomString& type, Init&& initializer)
60 {
61 return adoptRef(*new PointerEvent(type, WTFMove(initializer)));
62 }
63
64 static Ref<PointerEvent> createForPointerCapture(const AtomString& type, const PointerEvent& pointerEvent)
65 {
66 Init initializer;
67 initializer.bubbles = true;
68 initializer.pointerId = pointerEvent.pointerId();
69 initializer.isPrimary = pointerEvent.isPrimary();
70 initializer.pointerType = pointerEvent.pointerType();
71 return adoptRef(*new PointerEvent(type, WTFMove(initializer)));
72 }
73
74 static Ref<PointerEvent> createForBindings()
75 {
76 return adoptRef(*new PointerEvent);
77 }
78
79 static RefPtr<PointerEvent> create(short button, const MouseEvent&);
80 static Ref<PointerEvent> create(const String& type, short button, const MouseEvent&);
81 static Ref<PointerEvent> create(const String& type, PointerID, const String& pointerType, IsPrimary = IsPrimary::No);
82
83#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
84 static Ref<PointerEvent> create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
85 static Ref<PointerEvent> create(const String& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
86#endif
87
88 static const String& mousePointerType();
89 static const String& penPointerType();
90 static const String& touchPointerType();
91
92 virtual ~PointerEvent();
93
94 PointerID pointerId() const { return m_pointerId; }
95 double width() const { return m_width; }
96 double height() const { return m_height; }
97 float pressure() const { return m_pressure; }
98 float tangentialPressure() const { return m_tangentialPressure; }
99 long tiltX() const { return m_tiltX; }
100 long tiltY() const { return m_tiltY; }
101 long twist() const { return m_twist; }
102 String pointerType() const { return m_pointerType; }
103 bool isPrimary() const { return m_isPrimary; }
104
105 bool isPointerEvent() const final { return true; }
106
107 // https://w3c.github.io/pointerevents/#attributes-and-default-actions
108 // Many user agents expose non-standard attributes fromElement and toElement in MouseEvents to
109 // support legacy content. In those user agents, the values of those (inherited) attributes in
110 // PointerEvents must be null to encourage the use of the standardized alternates (i.e. target
111 // and relatedTarget).
112 RefPtr<Node> toElement() const final { return nullptr; }
113 RefPtr<Node> fromElement() const final { return nullptr; }
114
115 EventInterface eventInterface() const override;
116
117private:
118 static bool typeIsEnterOrLeave(const AtomString& type) { return type == eventNames().pointerenterEvent || type == eventNames().pointerleaveEvent; }
119 static CanBubble typeCanBubble(const AtomString& type) { return typeIsEnterOrLeave(type) ? CanBubble::No : CanBubble::Yes; }
120 static IsCancelable typeIsCancelable(const AtomString& type) { return typeIsEnterOrLeave(type) ? IsCancelable::No : IsCancelable::Yes; }
121 static IsComposed typeIsComposed(const AtomString& type) { return typeIsEnterOrLeave(type) ? IsComposed::No : IsComposed::Yes; }
122
123 PointerEvent();
124 PointerEvent(const AtomString&, Init&&);
125 PointerEvent(const AtomString& type, short button, const MouseEvent&);
126 PointerEvent(const AtomString& type, PointerID, const String& pointerType, IsPrimary);
127#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
128 PointerEvent(const AtomString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
129#endif
130
131 PointerID m_pointerId { mousePointerID };
132 double m_width { 1 };
133 double m_height { 1 };
134 float m_pressure { 0 };
135 float m_tangentialPressure { 0 };
136 long m_tiltX { 0 };
137 long m_tiltY { 0 };
138 long m_twist { 0 };
139 String m_pointerType { PointerEvent::mousePointerType() };
140 bool m_isPrimary { false };
141};
142
143} // namespace WebCore
144
145SPECIALIZE_TYPE_TRAITS_EVENT(PointerEvent)
146
147#endif // ENABLE(POINTER_EVENTS)
148