View Javadoc
1   /*
2    * Copyright (c) 2002-2025 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.html.DomNode;
23  import org.htmlunit.javascript.JavaScriptEngine;
24  import org.htmlunit.javascript.configuration.JsxClass;
25  import org.htmlunit.javascript.configuration.JsxConstructor;
26  import org.htmlunit.javascript.configuration.JsxGetter;
27  
28  /**
29   * JavaScript object representing a {@code PointerEvent}.
30   * @see <a href="http://www.w3.org/TR/pointerevents/">W3C Spec</a>
31   * @see <a href="http://msdn.microsoft.com/en-us/library/ie/hh772103.aspx">MSDN</a>
32   *
33   * @author Frank Danek
34   * @author Ahmed Ashour
35   * @author Ronald Brill
36   */
37  @JsxClass
38  public class PointerEvent extends MouseEvent {
39  
40      private int pointerId_;
41      private int width_;
42      private int height_;
43      private double pressure_;
44      private int tiltX_;
45      private int tiltY_;
46      private String pointerType_ = "";
47      private boolean isPrimary_;
48  
49      /**
50       * Default constructor.
51       */
52      public PointerEvent() {
53          super();
54      }
55  
56      /**
57       * JavaScript constructor.
58       * @param cx the current context
59       * @param scope the scope
60       * @param args the arguments to the WebSocket constructor
61       * @param ctorObj the function object
62       * @param inNewExpr Is new or not
63       * @return the java object to allow JavaScript to access
64       */
65      @JsxConstructor
66      public static Scriptable jsConstructor(final Context cx, final Scriptable scope,
67              final Object[] args, final Function ctorObj, final boolean inNewExpr) {
68          final PointerEvent event = new PointerEvent();
69          if (args.length != 0) {
70              event.setType(JavaScriptEngine.toString(args[0]));
71              event.setBubbles(false);
72              event.setCancelable(false);
73              event.width_ = 1;
74              event.height_ = 1;
75          }
76  
77          if (args.length > 1) {
78              final NativeObject object = (NativeObject) args[1];
79              event.setBubbles((boolean) getValue(object, "bubbles", event.isBubbles()));
80              event.pointerId_ = (int) getValue(object, "pointerId", event.pointerId_);
81              event.width_ = (int) getValue(object, "width", event.width_);
82              event.height_ = (int) getValue(object, "height", event.height_);
83              event.pressure_ = (double) getValue(object, "pressure", event.pressure_);
84              event.tiltX_ = (int) getValue(object, "tiltX", event.tiltX_);
85              event.tiltY_ = (int) getValue(object, "tiltY", event.tiltY_);
86              event.pointerType_ = (String) getValue(object, "pointerType", event.pointerType_);
87              event.isPrimary_ = (boolean) getValue(object, "isPrimary", event.isPrimary_);
88          }
89          return event;
90      }
91  
92      private static Object getValue(final ScriptableObject object, final String name, final Object defaulValue) {
93          Object value = object.get(name);
94          if (value == null) {
95              value = defaulValue;
96          }
97          else {
98              if (defaulValue instanceof String) {
99                  value = String.valueOf(value);
100             }
101             else if (defaulValue instanceof Double) {
102                 value = JavaScriptEngine.toNumber(value);
103             }
104             else if (defaulValue instanceof Number) {
105                 value = (int) JavaScriptEngine.toNumber(value);
106             }
107             else {
108                 value = JavaScriptEngine.toBoolean(value);
109             }
110         }
111         return value;
112     }
113 
114     /**
115      * Creates a new event instance.
116      *
117      * @param domNode the DOM node that triggered the event
118      * @param type the event type
119      * @param shiftKey true if SHIFT is pressed
120      * @param ctrlKey true if CTRL is pressed
121      * @param altKey true if ALT is pressed
122      * @param detail the detail value
123      * @param button the button code, must be {@link #BUTTON_LEFT}, {@link #BUTTON_MIDDLE} or {@link #BUTTON_RIGHT}
124      */
125     public PointerEvent(final DomNode domNode, final String type, final boolean shiftKey,
126             final boolean ctrlKey, final boolean altKey, final int button, final int detail) {
127         super(domNode, type, shiftKey, ctrlKey, altKey, button, detail);
128 
129         pointerId_ = 1;
130         width_ = 1;
131         height_ = 1;
132         pointerType_ = "mouse";
133         isPrimary_ = true;
134     }
135 
136     /**
137      * @return the pointerId
138      */
139     @JsxGetter
140     public long getPointerId() {
141         return pointerId_;
142     }
143 
144     /**
145      * @return the width
146      */
147     @JsxGetter
148     public long getWidth() {
149         return width_;
150     }
151 
152     /**
153      * @return the height
154      */
155     @JsxGetter
156     public long getHeight() {
157         return height_;
158     }
159 
160     /**
161      * @return the pressure
162      */
163     @JsxGetter
164     public double getPressure() {
165         return pressure_;
166     }
167 
168     /**
169      * @return the tiltX
170      */
171     @JsxGetter
172     public long getTiltX() {
173         return tiltX_;
174     }
175 
176     /**
177      * @return the tiltY
178      */
179     @JsxGetter
180     public long getTiltY() {
181         return tiltY_;
182     }
183 
184     /**
185      * @return the pointerType
186      */
187     @JsxGetter
188     public String getPointerType() {
189         return pointerType_;
190     }
191 
192     /**
193      * @return the isPrimary
194      */
195     @JsxGetter(propertyName = "isPrimary")
196     public boolean isPrimary_js() {
197         return isPrimary_;
198     }
199 
200     /**
201      * @return the pointerType
202      */
203     @JsxGetter
204     @SuppressWarnings("PMD.UseUnderscoresInNumericLiterals")
205     public double getAltitudeAngle() {
206         return 1.5707963267948966;
207     }
208 
209     /**
210      * @return the pointerType
211      */
212     @JsxGetter
213     public double getAzimuthAngle() {
214         return 0d;
215     }
216 
217     /**
218      * @return the persistentDeviceId
219      */
220     @JsxGetter
221     public double getPersistentDeviceId() {
222         // dummy but valid regarding to the spec
223         // https://w3c.github.io/pointerevents/#dom-pointerevent-persistentdeviceid
224         return 0d;
225     }
226 }