View Javadoc
1   /*
2    * Copyright (c) 2002-2026 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.event;
16  
17  import org.htmlunit.corejs.javascript.Context;
18  import org.htmlunit.corejs.javascript.Function;
19  import org.htmlunit.corejs.javascript.NativeObject;
20  import org.htmlunit.corejs.javascript.Scriptable;
21  import org.htmlunit.corejs.javascript.ScriptableObject;
22  import org.htmlunit.corejs.javascript.VarScope;
23  import org.htmlunit.html.DomNode;
24  import org.htmlunit.javascript.JavaScriptEngine;
25  import org.htmlunit.javascript.configuration.JsxClass;
26  import org.htmlunit.javascript.configuration.JsxConstructor;
27  import org.htmlunit.javascript.configuration.JsxGetter;
28  
29  /**
30   * JavaScript object representing a {@code PointerEvent}.
31   * @see <a href="http://www.w3.org/TR/pointerevents/">W3C Spec</a>
32   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent">MDN</a>
33   *
34   * @author Frank Danek
35   * @author Ahmed Ashour
36   * @author Ronald Brill
37   */
38  @JsxClass
39  public class PointerEvent extends MouseEvent {
40  
41      private int pointerId_;
42      private int width_;
43      private int height_;
44      private double pressure_;
45      private int tiltX_;
46      private int tiltY_;
47      private double altitudeAngle_;
48      private double azimuthAngle_;
49      private String pointerType_ = "";
50      private boolean isPrimary_;
51  
52      /**
53       * Default constructor.
54       */
55      public PointerEvent() {
56          super();
57      }
58  
59      /**
60       * JavaScript constructor.
61       * @param cx the current context
62       * @param scope the scope
63       * @param args the arguments to the WebSocket constructor
64       * @param ctorObj the function object
65       * @param inNewExpr Is new or not
66       * @return the java object to allow JavaScript to access
67       */
68      @JsxConstructor
69      public static Scriptable jsConstructor(final Context cx, final VarScope scope,
70              final Object[] args, final Function ctorObj, final boolean inNewExpr) {
71          final PointerEvent event = new PointerEvent();
72  
73          event.setBubbles(false);
74          event.setCancelable(false);
75  
76          event.altitudeAngle_ = Math.PI / 2d;
77  
78          if (args.length != 0) {
79              event.setType(JavaScriptEngine.toString(args[0]));
80              event.width_ = 1;
81              event.height_ = 1;
82          }
83  
84          if (args.length > 1) {
85              final NativeObject object = (NativeObject) args[1];
86              event.setBubbles((boolean) getValue(object, "bubbles", event.isBubbles()));
87  
88              event.pointerId_ = (int) getValue(object, "pointerId", event.pointerId_);
89              event.width_ = (int) getValue(object, "width", event.width_);
90              event.height_ = (int) getValue(object, "height", event.height_);
91              event.pressure_ = (double) getValue(object, "pressure", event.pressure_);
92              event.tiltX_ = (int) getValue(object, "tiltX", event.tiltX_);
93              event.tiltY_ = (int) getValue(object, "tiltY", event.tiltY_);
94              event.pointerType_ = (String) getValue(object, "pointerType", event.pointerType_);
95              event.isPrimary_ = (boolean) getValue(object, "isPrimary", event.isPrimary_);
96  
97              if (object.has("tiltX", object) || object.has("tiltY", object)) {
98                  event.altitudeAngle_ = 1.4105561004354874;
99                  event.azimuthAngle_ = 0.8628261898537035;
100             }
101         }
102         return event;
103     }
104 
105     private static Object getValue(final ScriptableObject object, final String name, final Object defaulValue) {
106         Object value = object.get(name);
107         if (value == null) {
108             value = defaulValue;
109         }
110         else {
111             if (defaulValue instanceof String) {
112                 value = String.valueOf(value);
113             }
114             else if (defaulValue instanceof Double) {
115                 value = JavaScriptEngine.toNumber(value);
116             }
117             else if (defaulValue instanceof Number) {
118                 value = (int) JavaScriptEngine.toNumber(value);
119             }
120             else {
121                 value = JavaScriptEngine.toBoolean(value);
122             }
123         }
124         return value;
125     }
126 
127     /**
128      * Creates a new event instance.
129      *
130      * @param domNode the DOM node that triggered the event
131      * @param type the event type
132      * @param shiftKey true if SHIFT is pressed
133      * @param ctrlKey true if CTRL is pressed
134      * @param altKey true if ALT is pressed
135      * @param detail the detail value
136      * @param button the button code, must be {@link #BUTTON_LEFT}, {@link #BUTTON_MIDDLE} or {@link #BUTTON_RIGHT}
137      */
138     public PointerEvent(final DomNode domNode, final String type, final boolean shiftKey,
139             final boolean ctrlKey, final boolean altKey, final int button, final int detail) {
140         super(domNode, type, shiftKey, ctrlKey, altKey, button, detail);
141 
142         pointerId_ = 1;
143         width_ = 1;
144         height_ = 1;
145         pointerType_ = "mouse";
146         isPrimary_ = true;
147     }
148 
149     /**
150      * Returns the pointer identifier.
151      *
152      * @return the pointer identifier
153      */
154     @JsxGetter
155     public long getPointerId() {
156         return pointerId_;
157     }
158 
159     /**
160      * Returns the pointer contact width.
161      *
162      * @return the pointer contact width
163      */
164     @JsxGetter
165     public long getWidth() {
166         return width_;
167     }
168 
169     /**
170      * Returns the pointer contact height.
171      *
172      * @return the pointer contact height
173      */
174     @JsxGetter
175     public long getHeight() {
176         return height_;
177     }
178 
179     /**
180      * Returns the normalized pointer pressure.
181      *
182      * @return the normalized pointer pressure
183      */
184     @JsxGetter
185     public double getPressure() {
186         return pressure_;
187     }
188 
189     /**
190      * Returns the pointer tilt along the X axis.
191      *
192      * @return the pointer tilt along the X axis
193      */
194     @JsxGetter
195     public long getTiltX() {
196         return tiltX_;
197     }
198 
199     /**
200      * Returns the pointer tilt along the Y axis.
201      *
202      * @return the pointer tilt along the Y axis
203      */
204     @JsxGetter
205     public long getTiltY() {
206         return tiltY_;
207     }
208 
209     /**
210      * Returns the pointer type.
211      *
212      * @return the pointer type
213      */
214     @JsxGetter
215     public String getPointerType() {
216         return pointerType_;
217     }
218 
219     /**
220      * Returns whether this is the primary pointer.
221      *
222      * @return whether this is the primary pointer
223      */
224     @JsxGetter(propertyName = "isPrimary")
225     public boolean isPrimary_js() {
226         return isPrimary_;
227     }
228 
229     /**
230      * Returns the pointer altitude angle.
231      *
232      * @return the pointer altitude angle
233      */
234     @JsxGetter
235     @SuppressWarnings("PMD.UseUnderscoresInNumericLiterals")
236     public double getAltitudeAngle() {
237         return altitudeAngle_;
238     }
239 
240     /**
241      * Returns the pointer azimuth angle.
242      *
243      * @return the pointer azimuth angle
244      */
245     @JsxGetter
246     public double getAzimuthAngle() {
247         return azimuthAngle_;
248     }
249 
250     /**
251      * Returns the persistent device identifier.
252      *
253      * @return the persistent device identifier
254      */
255     @JsxGetter
256     public double getPersistentDeviceId() {
257         // dummy but valid regarding the spec
258         // https://w3c.github.io/pointerevents/#dom-pointerevent-persistentdeviceid
259         return 0d;
260     }
261 }