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 static org.htmlunit.javascript.configuration.SupportedBrowser.FF; 18 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR; 19 20 import java.util.ArrayList; 21 22 import org.htmlunit.ScriptResult; 23 import org.htmlunit.corejs.javascript.Context; 24 import org.htmlunit.corejs.javascript.Scriptable; 25 import org.htmlunit.corejs.javascript.ScriptableObject; 26 import org.htmlunit.html.DomNode; 27 import org.htmlunit.javascript.HtmlUnitScriptable; 28 import org.htmlunit.javascript.JavaScriptEngine; 29 import org.htmlunit.javascript.configuration.JsxClass; 30 import org.htmlunit.javascript.configuration.JsxConstant; 31 import org.htmlunit.javascript.configuration.JsxConstructor; 32 import org.htmlunit.javascript.configuration.JsxFunction; 33 import org.htmlunit.javascript.configuration.JsxGetter; 34 import org.htmlunit.javascript.configuration.JsxSetter; 35 36 /** 37 * JavaScript object representing an event that is passed into event handlers when they are 38 * invoked. For general information on which properties and functions should be supported, 39 * see <a href="https://developer.mozilla.org/en-US/docs/DOM/event">the mozilla docs</a>, 40 * <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event">the W3C DOM 41 * Level 2 Event Documentation</a> or <a href="http://msdn2.microsoft.com/en-us/library/aa703876.aspx">IE's 42 * IHTMLEventObj interface</a>. 43 * 44 * @author <a href="mailto:chriseldredge@comcast.net">Chris Eldredge</a> 45 * @author Mike Bowler 46 * @author Chris Erskine 47 * @author Marc Guillemot 48 * @author Daniel Gredler 49 * @author Brad Murray 50 * @author Ahmed Ashour 51 * @author Rob Di Marco 52 * @author Ronald Brill 53 * @author Frank Danek 54 * @author Atsushi Nakagawa 55 * @author Thorsten Wendelmuth 56 */ 57 @JsxClass 58 public class Event extends HtmlUnitScriptable { 59 60 /** 61 * Key to place the event's target in the Context's scope during event processing 62 * to compute node coordinates compatible with those of the event. 63 */ 64 protected static final String KEY_CURRENT_EVENT = "Event#current"; 65 66 /** The submit event type, triggered by {@code onsubmit} event handlers. */ 67 public static final String TYPE_SUBMIT = "submit"; 68 69 /** The change event type, triggered by {@code onchange} event handlers. */ 70 public static final String TYPE_CHANGE = "change"; 71 72 /** The load event type, triggered by {@code onload} event handlers. */ 73 public static final String TYPE_LOAD = "load"; 74 75 /** The unload event type, triggered by {@code onunload} event handlers. */ 76 public static final String TYPE_UNLOAD = "unload"; 77 78 /** The popstate event type, triggered by {@code onpopstate} event handlers. */ 79 public static final String TYPE_POPSTATE = "popstate"; 80 81 /** The focus event type, triggered by {@code onfocus} event handlers. */ 82 public static final String TYPE_FOCUS = "focus"; 83 84 /** The focus in event type, triggered by {@code onfocusin} event handlers. */ 85 public static final String TYPE_FOCUS_IN = "focusin"; 86 87 /** The focus out event type, triggered by {@code onfocusout} event handlers. */ 88 public static final String TYPE_FOCUS_OUT = "focusout"; 89 90 /** The blur event type, triggered by {@code onblur} event handlers. */ 91 public static final String TYPE_BLUR = "blur"; 92 93 /** The key down event type, triggered by {@code onkeydown} event handlers. */ 94 public static final String TYPE_KEY_DOWN = "keydown"; 95 96 /** The key down event type, triggered by {@code onkeypress} event handlers. */ 97 public static final String TYPE_KEY_PRESS = "keypress"; 98 99 /** The input event type, triggered by {@code oninput} event handlers. */ 100 public static final String TYPE_INPUT = "input"; 101 102 /** The key down event type, triggered by {@code onkeyup} event handlers. */ 103 public static final String TYPE_KEY_UP = "keyup"; 104 105 /** The submit event type, triggered by {@code onreset} event handlers. */ 106 public static final String TYPE_RESET = "reset"; 107 108 /** The beforeunload event type, triggered by {@code onbeforeunload} event handlers. */ 109 public static final String TYPE_BEFORE_UNLOAD = "beforeunload"; 110 111 /** Triggered after the DOM has loaded but before images etc. */ 112 public static final String TYPE_DOM_DOCUMENT_LOADED = "DOMContentLoaded"; 113 114 /** The event type triggered by {@code onpropertychange} event handlers. */ 115 public static final String TYPE_PROPERTY_CHANGE = "propertychange"; 116 117 /** The event type triggered by {@code onhashchange} event handlers. */ 118 public static final String TYPE_HASH_CHANGE = "hashchange"; 119 120 /** The event type triggered by {@code onreadystatechange} event handlers. */ 121 public static final String TYPE_READY_STATE_CHANGE = "readystatechange"; 122 123 /** The event type triggered by {@code onerror} event handlers. */ 124 public static final String TYPE_ERROR = "error"; 125 126 /** The message event type, triggered by postMessage. */ 127 public static final String TYPE_MESSAGE = "message"; 128 129 /** The close event type, triggered by {@code onclose} event handlers. */ 130 public static final String TYPE_CLOSE = "close"; 131 132 /** The open event type, triggered by {@code onopen} event handlers. */ 133 public static final String TYPE_OPEN = "open"; 134 135 /** The load start event type, triggered by {@code onloadstart} event handlers. */ 136 public static final String TYPE_LOAD_START = "loadstart"; 137 138 /** The load end event type, triggered by {@code onloadend} event handlers. */ 139 public static final String TYPE_LOAD_END = "loadend"; 140 141 /** The progress event type, triggered by {@code onprogress} event handlers. */ 142 public static final String TYPE_PROGRESS = "progress"; 143 144 /** The abort event type, triggered by {@code onabort} event handlers. */ 145 public static final String TYPE_ABORT = "abort"; 146 147 /** The timeout event type, triggered by {@code ontimeout} event handlers. */ 148 public static final String TYPE_TIMEOUT = "timeout"; 149 150 /** The scroll event type, triggered by {@code onscroll} event handlers. */ 151 public static final String TYPE_SCROLL = "scroll"; 152 153 /** The scroll event type, triggered by {@code onscrollend} event handlers. */ 154 public static final String TYPE_SCROLLEND = "scrollend"; 155 156 /** The search event type, triggered by {@code onsearch} event handlers. */ 157 public static final String TYPE_SEARCH = "search"; 158 159 /** The dragend event type, triggered by {@code dragend} event handlers. */ 160 public static final String TYPE_DRAGEND = "dragend"; 161 162 /** The invalid event type, triggered by {@code invalid} event handlers. */ 163 public static final String TYPE_INVALID = "invalid"; 164 165 /** The pointerout event type, triggered by {@code pointerout} event handlers. */ 166 public static final String TYPE_POINTEROUT = "pointerout"; 167 168 /** The ratechange event type, triggered by {@code ratechange} event handlers. */ 169 public static final String TYPE_RATECHANGE = "ratechange"; 170 171 /** The animationiteration event type, triggered by {@code animationiteration} event handlers. */ 172 public static final String TYPE_ANIMATIONITERATION = "animationiteration"; 173 174 /** The canplaythrough event type, triggered by {@code canplaythrough} event handlers. */ 175 public static final String TYPE_CANPLAYTHROUGH = "canplaythrough"; 176 177 /** The cancel event type, triggered by {@code cancel} event handlers. */ 178 public static final String TYPE_CANCEL = "cancel"; 179 180 /** The pointerenter event type, triggered by {@code pointerenter} event handlers. */ 181 public static final String TYPE_POINTERENTER = "pointerenter"; 182 183 /** The select event type, triggered by {@code select} event handlers. */ 184 public static final String TYPE_SELECT = "select"; 185 186 /** The auxclick event type, triggered by {@code auxclick} event handlers. */ 187 public static final String TYPE_AUXCLICK = "auxclick"; 188 189 // /** The mspointerleave event type, triggered by {@code mspointerleave} event handlers. */ 190 // public static final String TYPE_MSPOINTERLEAVE = "mspointerleave"; 191 // 192 /** The webkitanimationstart event type, triggered by {@code webkitanimationstart} event handlers. */ 193 public static final String TYPE_WEBANIMATIONSTART = "webkitanimationstart"; 194 195 // /** The msgesturestart event type, triggered by {@code msgesturestart} event handlers. */ 196 // public static final String TYPE_MSGESTURESTART = "msgesturestart"; 197 198 /** The drag event type, triggered by {@code drag} event handlers. */ 199 public static final String TYPE_DRAG = "drag"; 200 201 /** The seeked event type, triggered by {@code seeked} event handlers. */ 202 public static final String TYPE_SEEKED = "seeked"; 203 204 /** The offline event type, triggered by {@code offline} event handlers. */ 205 public static final String TYPE_OFFLINE = "offline"; 206 207 /** The deviceorientation event type, triggered by {@code deviceorientation} event handlers. */ 208 public static final String TYPE_DEVICEORIENTATION = "deviceorientation"; 209 210 /** The toggle event type, triggered by {@code toggle} event handlers. */ 211 public static final String TYPE_TOGGLE = "toggle"; 212 213 /** The play event type, triggered by {@code play} event handlers. */ 214 public static final String TYPE_PLAY = "play"; 215 216 /** The loadedmetadata event type, triggered by {@code loadedmetadata} event handlers. */ 217 public static final String TYPE_LOADEDMETADATA = "loadedmetadata"; 218 219 /** The pointermove event type, triggered by {@code pointermove} event handlers. */ 220 public static final String TYPE_POINTERMOVE = "pointermove"; 221 222 /** The lostpointercapture event type, triggered by {@code lostpointercapture} event handlers. */ 223 public static final String TYPE_LOSTPOINTERCAPTURE = "lostpointercapture"; 224 225 /** The pointerover event type, triggered by {@code pointerover} event handlers. */ 226 public static final String TYPE_POINTEROVER = "pointerover"; 227 228 /** The animationcancel event type, triggered by {@code animationcancel} event handlers. */ 229 public static final String TYPE_ANIMATIONCANCEL = "animationcancel"; 230 231 /** The animationend event type, triggered by {@code animationend} event handlers. */ 232 public static final String TYPE_ANIMATIONEND = "animationend"; 233 234 /** The dragenter event type, triggered by {@code dragenter} event handlers. */ 235 public static final String TYPE_DRAGENTER = "dragenter"; 236 237 /** The afterprint event type, triggered by {@code afterprint} event handlers. */ 238 public static final String TYPE_AFTERPRINT = "afterprint"; 239 240 /** The mozfullscreenerror event type, triggered by {@code mozfullscreenerror} event handlers. */ 241 public static final String TYPE_MOZFULLSCREENERROR = "mozfullscreenerror"; 242 243 /** The mouseleave event type, triggered by {@code mouseleave} event handlers. */ 244 public static final String TYPE_MOUSELEAVE = "mouseleave"; 245 246 /** The mousewheel event type, triggered by {@code mousewheel} event handlers. */ 247 public static final String TYPE_MOUSEWHEEL = "mousewheel"; 248 249 /** The seeking event type, triggered by {@code seeking} event handlers. */ 250 public static final String TYPE_SEEKING = "seeking"; 251 252 /** The cuechange event type, triggered by {@code cuechange} event handlers. */ 253 public static final String TYPE_CUECHANGE = "cuechange"; 254 255 /** The pageshow event type, triggered by {@code pageshow} event handlers. */ 256 public static final String TYPE_PAGESHOW = "pageshow"; 257 258 // /** The mspointerenter event type, triggered by {@code mspointerenter} event handlers. */ 259 // public static final String TYPE_MSPOINTENTER = "mspointerenter"; 260 261 /** The mozfullscreenchange event type, triggered by {@code mozfullscreenchange} event handlers. */ 262 public static final String TYPE_MOZFULLSCREENCHANGE = "mozfullscreenchange"; 263 264 /** The durationchange event type, triggered by {@code durationchange} event handlers. */ 265 public static final String TYPE_DURATIONCHANGE = "durationchange"; 266 267 /** The playing event type, triggered by {@code playing} event handlers. */ 268 public static final String TYPE_PLAYING = "playing"; 269 270 /** The ended event type, triggered by {@code ended} event handlers. */ 271 public static final String TYPE_ENDED = "ended"; 272 273 /** The loadeddata event type, triggered by {@code loadeddata} event handlers. */ 274 public static final String TYPE_LOADEDDATA = "loadeddata"; 275 276 /** The unhandledrejection event type, triggered by {@code unhandledrejection} event handlers. */ 277 public static final String TYPE_UNHANDLEDREJECTION = "unhandledrejection"; 278 279 /** The suspend event type, triggered by {@code suspend} event handlers. */ 280 public static final String TYPE_SUSPEND = "suspend"; 281 282 /** The waiting event type, triggered by {@code waiting} event handlers. */ 283 public static final String TYPE_WAITING = "waiting"; 284 285 /** The canplay event type, triggered by {@code canplay} event handlers. */ 286 public static final String TYPE_CANPLAY = "canplay"; 287 288 /** The languagechange event type, triggered by {@code languagechange} event handlers. */ 289 public static final String TYPE_LANGUAGECHANGE = "languagechange"; 290 291 /** The emptied event type, triggered by {@code emptied} event handlers. */ 292 public static final String TYPE_EMPTIED = "emptied"; 293 294 /** The rejectionhandled event type, triggered by {@code rejectionhandled} event handlers. */ 295 public static final String TYPE_REJECTIONHANDLED = "rejectionhandled"; 296 297 /** The pointercancel event type, triggered by {@code pointercancel} event handlers. */ 298 public static final String TYPE_POINTERCANCEL = "pointercancel"; 299 300 /** The resize event type, triggered by {@code resize} event handlers. */ 301 public static final String TYPE_RESIZE = "resize"; 302 303 /** The pause event type, triggered by {@code pause} event handlers. */ 304 public static final String TYPE_PAUSE = "pause"; 305 306 /** The pointerup event type, triggered by {@code pointerup} event handlers. */ 307 public static final String TYPE_POINTERUP = "pointerup"; 308 309 /** The wheel event type, triggered by {@code wheel} event handlers. */ 310 public static final String TYPE_WHEEL = "wheel"; 311 312 /** The pointerleave event type, triggered by {@code pointerleave} event handlers. */ 313 public static final String TYPE_POINTERLEAVE = "pointerleave"; 314 315 /** The beforeprint event type, triggered by {@code beforeprint} event handlers. */ 316 public static final String TYPE_BEFOREPRINT = "beforeprint"; 317 318 /** The storage event type, triggered by {@code storage} event handlers. */ 319 public static final String TYPE_STORAGE = "storage"; 320 321 /** The animationstart event type, triggered by {@code animationstart} event handlers. */ 322 public static final String TYPE_ANIMATIONSTART = "animationstart"; 323 324 /** The timeupdate event type, triggered by {@code timeupdate} event handlers. */ 325 public static final String TYPE_TIMEUPDATE = "timeupdate"; 326 327 /** The pagehide event type, triggered by {@code pagehide} event handlers. */ 328 public static final String TYPE_PAGEHIDE = "pagehide"; 329 330 /** The webkitanimationiteration event type, triggered by {@code webkitanimationiteration} event handlers. */ 331 public static final String TYPE_WEBKITANIMATIONITERATION = "webkitanimationiteration"; 332 333 /** The dragover event type, triggered by {@code dragover} event handlers. */ 334 public static final String TYPE_DRAGOVER = "dragover"; 335 336 /** The online event type, triggered by {@code online} event handlers. */ 337 public static final String TYPE_ONLINE = "online"; 338 339 /** The volumechange event type, triggered by {@code volumechange} event handlers. */ 340 public static final String TYPE_VOLUMECHANGE = "volumechange"; 341 342 /** The gotpointercapture event type, triggered by {@code gotpointercapture} event handlers. */ 343 public static final String TYPE_GOTPOINTERCAPTURE = "gotpointercapture"; 344 345 /** The webkittransitionend event type, triggered by {@code webkittransitionend} event handlers. */ 346 public static final String TYPE_WEBKITTRANSITIONEND = "webkittransitionend"; 347 348 /** The webkitanimationend event type, triggered by {@code webkitanimationend} event handlers. */ 349 public static final String TYPE_WEBKITANIMATIONEND = "webkitanimationend"; 350 351 /** The devicemotion event type, triggered by {@code devicemotion} event handlers. */ 352 public static final String TYPE_DEVICEMOTION = "devicemotion"; 353 354 /** The stalled event type, triggered by {@code stalled} event handlers. */ 355 public static final String TYPE_STALLED = "stalled"; 356 357 /** The mouseenter event type, triggered by {@code mouseenter} event handlers. */ 358 public static final String TYPE_MOUDEENTER = "mouseenter"; 359 360 /** The dragleave event type, triggered by {@code dragleave} event handlers. */ 361 public static final String TYPE_DRAGLEAVE = "dragleave"; 362 363 /** The pointerdown event type, triggered by {@code pointerdown} event handlers. */ 364 public static final String TYPE_POINTERDOWN = "pointerdown"; 365 366 /** The drop event type, triggered by {@code drop} event handlers. */ 367 public static final String TYPE_DROP = "drop"; 368 369 /** The dragstart event type, triggered by {@code dragstart} event handlers. */ 370 public static final String TYPE_DRAGSTART = "dragstart"; 371 372 /** The transitionend event type, triggered by {@code transitionend} event handlers. */ 373 public static final String TYPE_TRANSITIONEND = "transitionend"; 374 375 // /** The msgesturehold event type, triggered by {@code msgesturehold} event handlers. */ 376 // public static final String TYPE_MSGESTUREHOLD = "msgesturehold"; 377 378 /** The deviceorientationabsolute event type, triggered by {@code deviceorientationabsolute} event handlers. */ 379 public static final String TYPE_DEVICEORIENTATIONABSOLUTE = "deviceorientationabsolute"; 380 381 /** The beforecopy event type, triggered by {@code beforecopy} event handlers. */ 382 public static final String TYPE_BEFORECOPY = "beforecopy"; 383 384 /** The beforecut event type, triggered by {@code beforecut} event handlers. */ 385 public static final String TYPE_BEFORECUT = "beforecut"; 386 387 /** The beforepaste event type, triggered by {@code beforepaste} event handlers. */ 388 public static final String TYPE_BEFOREPASTE = "beforepaste"; 389 390 /** The selectstart event type, triggered by {@code selectstart} event handlers. */ 391 public static final String TYPE_SELECTSTART = "selectstart"; 392 393 /** The webkitfullscreenchange event type, triggered by {@code webkitfullscreenchange} event handlers. */ 394 public static final String TYPE_WEBKITFULLSCREENCHANGE = "webkitfullscreenchange"; 395 396 /** The webkitfullscreenerror event type, triggered by {@code webkitfullscreenerror} event handlers. */ 397 public static final String TYPE_WEBKITFULLSCREENERROR = "webkitfullscreenerror"; 398 399 /** The copy event type, triggered by {@code copy} event handlers. */ 400 public static final String TYPE_COPY = "copy"; 401 402 /** The cut event type, triggered by {@code cut} event handlers. */ 403 public static final String TYPE_CUT = "cut"; 404 405 /** The paste event type, triggered by {@code paste} event handlers. */ 406 public static final String TYPE_PASTE = "paste"; 407 408 /** The onmessageerror event type, triggered by {@code onmessageerror} event handlers. */ 409 public static final String TYPE_ONMESSAGEERROR = "onmessageerror"; 410 411 /** The pointerlockchange event type, triggered by {@code pointerlockchange} event handlers. */ 412 public static final String TYPE_POINTERLOCKCHANGE = "pointerlockchange"; 413 414 /** The pointerlockerror event type, triggered by {@code pointerlockerror} event handlers. */ 415 public static final String TYPE_POINTERLOCKERROR = "pointerlockerror"; 416 417 /** The selectionchange event type, triggered by {@code selectionchange} event handlers. */ 418 public static final String TYPE_SELECTIONCHANGE = "selectionchange"; 419 420 /** The afterscriptexecute event type, triggered by {@code afterscriptexecute} event handlers. */ 421 public static final String TYPE_AFTERSCRIPTEXECUTE = "afterscriptexecute"; 422 423 /** The beforescriptexecute event type, triggered by {@code beforescriptexecute} event handlers. */ 424 public static final String TYPE_BEFORESCRIPTEXECUTE = "beforescriptexecute"; 425 426 /** The ontransitioncancel event type, triggered by {@code ontransitioncancel} event handlers. */ 427 public static final String TYPE_ONTRANSITIONCANCEL = "ontransitioncancel"; 428 429 /** The ontransitionend event type, triggered by {@code ontransitionend} event handlers. */ 430 public static final String TYPE_ONTRANSITIONEND = "ontransitionend"; 431 432 /** The ontransitionrun event type, triggered by {@code ontransitionrun} event handlers. */ 433 public static final String TYPE_ONTRANSITIONRUN = "ontransitionrun"; 434 435 /** The ontransitionstart event type, triggered by {@code ontransitionstart} event handlers. */ 436 public static final String TYPE_ONTRANSITIONSTART = "ontransitionstart"; 437 438 /** The ongamepadconnected event type, triggered by {@code ongamepadconnected} event handlers. */ 439 public static final String TYPE_GAMEPAD_CONNECTED = "ongamepadconnected"; 440 441 /** The ongamepaddisconnected event type, triggered by {@code ongamepaddisconnected} event handlers. */ 442 public static final String TYPE_GAMEPAD_DISCONNECTED = "ongamepaddisconnected"; 443 444 /** 445 * The mssitemodejumplistitemremoved event type, triggered 446 * by {@code mssitemodejumplistitemremoved} event handlers. 447 */ 448 public static final String TYPE_MSSITEMODEJUMPLISTITEMREMOVED = "mssitemodejumplistitemremoved"; 449 450 /** No event phase. */ 451 @JsxConstant 452 public static final int NONE = 0; 453 454 /** The first event phase: the capturing phase. */ 455 @JsxConstant 456 public static final int CAPTURING_PHASE = 1; 457 458 /** The second event phase: at the event target. */ 459 @JsxConstant 460 public static final int AT_TARGET = 2; 461 462 /** The third (and final) event phase: the bubbling phase. */ 463 @JsxConstant 464 public static final int BUBBLING_PHASE = 3; 465 466 /** Constant. */ 467 @JsxConstant({FF, FF_ESR}) 468 public static final int ALT_MASK = 0x1; 469 470 /** Constant. */ 471 @JsxConstant({FF, FF_ESR}) 472 public static final int CONTROL_MASK = 0x2; 473 474 /** Constant. */ 475 @JsxConstant({FF, FF_ESR}) 476 public static final int SHIFT_MASK = 0x4; 477 478 /** Constant. */ 479 @JsxConstant({FF, FF_ESR}) 480 public static final int META_MASK = 0x8; 481 482 private Object srcElement_; // writable equivalent of target. 483 private EventTarget target_; // W3C standard read-only equivalent of srcElement. 484 private Scriptable currentTarget_; // Changes during event capturing and bubbling. 485 private String type_ = ""; // The event type. 486 private int keyCode_; // Key code for a keypress 487 private boolean shiftKey_; 488 private boolean ctrlKey_; 489 private boolean altKey_; 490 private String propertyName_; 491 private boolean stopPropagation_; 492 private boolean stopImmediatePropagation_; 493 private boolean preventDefault_; 494 495 /** 496 * The current event phase. This is a W3C standard attribute. One of {@link #NONE}, 497 * {@link #CAPTURING_PHASE}, {@link #AT_TARGET} or {@link #BUBBLING_PHASE}. 498 */ 499 private int eventPhase_; 500 501 /** 502 * Whether or not the event bubbles. The value of this attribute depends on the event type. To 503 * determine if a certain event type bubbles, see 504 * <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html">events</a> 505 * Most event types do bubble, so this is true by default; event types which do not bubble should 506 * overwrite this value in their constructors. 507 */ 508 private boolean bubbles_ = true; 509 510 /** 511 * Whether or not the event can be canceled. The value of this attribute depends on the event type. To 512 * determine if a certain event type can be canceled, see 513 * <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html"> 514 * http://www.w3.org/TR/DOM-Level-2-Events/events.html</a> 515 * The more common event types are cancelable, so this is true by default; event types which cannot be 516 * canceled should overwrite this value in their constructors. 517 */ 518 private boolean cancelable_ = true; 519 520 /** 521 * The time at which the event was created. 522 */ 523 private final long timeStamp_ = System.currentTimeMillis(); 524 525 /** 526 * Creates a new event instance. 527 * @param domNode the DOM node that triggered the event 528 * @param type the event type 529 */ 530 public Event(final DomNode domNode, final String type) { 531 this((EventTarget) domNode.getScriptableObject(), type); 532 setDomNode(domNode, false); 533 } 534 535 /** 536 * Creates a new event instance. 537 * @param target the target 538 * @param type the event type 539 */ 540 public Event(final EventTarget target, final String type) { 541 this(type); 542 543 srcElement_ = target; 544 target_ = target; 545 currentTarget_ = target; 546 547 setParentScope(target); 548 setPrototype(getPrototype(getClass())); 549 550 if (TYPE_CHANGE.equals(type)) { 551 cancelable_ = false; 552 } 553 else if (TYPE_LOAD.equals(type) 554 || TYPE_CLOSE.equals(type)) { 555 bubbles_ = false; 556 cancelable_ = false; 557 } 558 else if (TYPE_ERROR.equals(type)) { 559 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-error 560 bubbles_ = false; 561 } 562 else if ( 563 TYPE_FOCUS.equals(type) 564 || TYPE_BLUR.equals(type) 565 || TYPE_BEFOREPRINT.equals(type) 566 || TYPE_AFTERPRINT.equals(type)) { 567 bubbles_ = false; 568 cancelable_ = false; 569 } 570 } 571 572 /** 573 * Creates a new event instance. 574 * @param type the event type 575 */ 576 public Event(final String type) { 577 super(); 578 type_ = type; 579 } 580 581 /** 582 * Creates a new Event with {@link #TYPE_PROPERTY_CHANGE} type. 583 * @param domNode the DOM node that triggered the event 584 * @param propertyName the property name that was changed 585 * @return the new Event object 586 */ 587 public static Event createPropertyChangeEvent(final DomNode domNode, final String propertyName) { 588 final Event event = new Event(domNode, TYPE_PROPERTY_CHANGE); 589 event.propertyName_ = propertyName; 590 return event; 591 } 592 593 /** 594 * Used to build the prototype. 595 */ 596 public Event() { 597 super(); 598 } 599 600 /** 601 * Called whenever an event is created using <code>Document.createEvent(..)</code>. 602 * This method is called after the parent scope was set so you are able to access the browser version. 603 */ 604 public void eventCreated() { 605 setBubbles(false); 606 setCancelable(false); 607 } 608 609 /** 610 * JavaScript constructor. 611 * 612 * @param type the event type 613 * @param details the event details (optional) 614 */ 615 @JsxConstructor 616 public void jsConstructor(final String type, final ScriptableObject details) { 617 boolean bubbles = false; 618 boolean cancelable = false; 619 620 if (details != null && !JavaScriptEngine.isUndefined(details)) { 621 bubbles = JavaScriptEngine.toBoolean(details.get("bubbles")); 622 cancelable = JavaScriptEngine.toBoolean(details.get("cancelable")); 623 } 624 initEvent(type, bubbles, cancelable); 625 } 626 627 /** 628 * Called when the event starts being fired. 629 */ 630 @SuppressWarnings("unchecked") 631 public void startFire() { 632 final Context context = Context.getCurrentContext(); 633 ArrayList<Event> events = (ArrayList<Event>) context.getThreadLocal(KEY_CURRENT_EVENT); 634 if (events == null) { 635 events = new ArrayList<>(); 636 context.putThreadLocal(KEY_CURRENT_EVENT, events); 637 } 638 events.add(this); 639 } 640 641 /** 642 * Called when the event being fired ends. 643 */ 644 @SuppressWarnings("unchecked") 645 public void endFire() { 646 final Context context = Context.getCurrentContext(); 647 final ArrayList<Event> events = (ArrayList<Event>) context.getThreadLocal(KEY_CURRENT_EVENT); 648 if (events != null && events.size() > 0) { 649 events.remove(events.size() - 1); 650 } 651 } 652 653 /** 654 * Returns the object that fired the event. 655 * @return the object that fired the event 656 */ 657 @JsxGetter 658 public Object getSrcElement() { 659 return srcElement_; 660 } 661 662 /** 663 * Sets the object that fired the event. 664 * @param srcElement the object that fired the event 665 */ 666 public void setSrcElement(final Object srcElement) { 667 srcElement_ = srcElement; 668 } 669 670 /** 671 * Returns the event target to which the event was originally dispatched. 672 * @return the event target to which the event was originally dispatched 673 */ 674 @JsxGetter 675 public Object getTarget() { 676 return target_; 677 } 678 679 /** 680 * Sets the event target. 681 * @param target the event target 682 */ 683 public void setTarget(final EventTarget target) { 684 target_ = target; 685 } 686 687 /** 688 * Returns the event target whose event listeners are currently being processed. This 689 * is useful during event capturing and event bubbling. 690 * @return the current event target 691 */ 692 @JsxGetter 693 public Scriptable getCurrentTarget() { 694 return currentTarget_; 695 } 696 697 /** 698 * Sets the current target. 699 * @param target the new value 700 */ 701 public void setCurrentTarget(final Scriptable target) { 702 currentTarget_ = target; 703 } 704 705 /** 706 * Returns the event type. 707 * @return the event type 708 */ 709 @JsxGetter 710 public String getType() { 711 return type_; 712 } 713 714 /** 715 * Sets the event type. 716 * @param type the event type 717 */ 718 public void setType(final String type) { 719 type_ = type; 720 } 721 722 /** 723 * Sets the event type. 724 * @param eventType the event type 725 */ 726 public void setEventType(final String eventType) { 727 type_ = eventType; 728 } 729 730 /** 731 * Returns the time at which this event was created. 732 * @return the time at which this event was created 733 */ 734 @JsxGetter 735 public long getTimeStamp() { 736 return timeStamp_; 737 } 738 739 /** 740 * Sets the key code. 741 * @param keyCode the virtual key code value of the key which was depressed, otherwise zero 742 */ 743 protected void setKeyCode(final int keyCode) { 744 keyCode_ = keyCode; 745 } 746 747 /** 748 * Returns the key code associated with the event. 749 * @return the key code associated with the event 750 */ 751 public int getKeyCode() { 752 return keyCode_; 753 } 754 755 /** 756 * Returns whether {@code SHIFT} has been pressed during this event or not. 757 * @return whether {@code SHIFT} has been pressed during this event or not 758 */ 759 public boolean isShiftKey() { 760 return shiftKey_; 761 } 762 763 /** 764 * Sets whether {@code SHIFT} key is pressed on not. 765 * @param shiftKey whether {@code SHIFT} has been pressed during this event or not 766 */ 767 protected void setShiftKey(final boolean shiftKey) { 768 shiftKey_ = shiftKey; 769 } 770 771 /** 772 * Returns whether {@code CTRL} has been pressed during this event or not. 773 * @return whether {@code CTRL} has been pressed during this event or not 774 */ 775 public boolean isCtrlKey() { 776 return ctrlKey_; 777 } 778 779 /** 780 * Sets whether {@code CTRL} key is pressed on not. 781 * @param ctrlKey whether {@code CTRL} has been pressed during this event or not 782 */ 783 protected void setCtrlKey(final boolean ctrlKey) { 784 ctrlKey_ = ctrlKey; 785 } 786 787 /** 788 * Returns whether {@code ALT} has been pressed during this event or not. 789 * @return whether {@code ALT} has been pressed during this event or not 790 */ 791 public boolean isAltKey() { 792 return altKey_; 793 } 794 795 /** 796 * Sets whether {@code ALT} key is pressed on not. 797 * @param altKey whether {@code ALT} has been pressed during this event or not 798 */ 799 protected void setAltKey(final boolean altKey) { 800 altKey_ = altKey; 801 } 802 803 /** 804 * Returns the current event phase for the event. 805 * @return the current event phase for the event 806 */ 807 @JsxGetter 808 public int getEventPhase() { 809 return eventPhase_; 810 } 811 812 /** 813 * Sets the current event phase. Must be one of {@link #CAPTURING_PHASE}, {@link #AT_TARGET} or 814 * {@link #BUBBLING_PHASE}. 815 * 816 * @param phase the phase the event is in 817 */ 818 public void setEventPhase(final int phase) { 819 if (phase != CAPTURING_PHASE && phase != AT_TARGET && phase != BUBBLING_PHASE) { 820 throw new IllegalArgumentException("Illegal phase specified: " + phase); 821 } 822 eventPhase_ = phase; 823 } 824 825 /** 826 * @return whether or not this event bubbles 827 */ 828 @JsxGetter 829 public boolean isBubbles() { 830 return bubbles_; 831 } 832 833 /** 834 * @param bubbles the bubbles to set 835 */ 836 protected void setBubbles(final boolean bubbles) { 837 bubbles_ = bubbles; 838 } 839 840 /** 841 * @return whether or not this event can be canceled 842 */ 843 @JsxGetter 844 public boolean isCancelable() { 845 return cancelable_; 846 } 847 848 /** 849 * @param cancelable the cancelable to set 850 */ 851 protected void setCancelable(final boolean cancelable) { 852 cancelable_ = cancelable; 853 } 854 855 /** 856 * Returns {@code true} if both <code>cancelable</code> is {@code true} and <code>preventDefault()</code> has been 857 * called for this event. Otherwise this attribute must return {@code false}. 858 * @return {@code true} if this event has been cancelled or not 859 */ 860 @JsxGetter 861 public boolean isDefaultPrevented() { 862 return cancelable_ && preventDefault_; 863 } 864 865 /** 866 * @return indicates if event propagation is stopped 867 */ 868 @JsxGetter 869 public boolean isCancelBubble() { 870 return stopPropagation_; 871 } 872 873 /** 874 * @param newValue indicates if event propagation is stopped 875 */ 876 @JsxSetter 877 public void setCancelBubble(final boolean newValue) { 878 stopPropagation_ = newValue; 879 } 880 881 /** 882 * Stops the event from propagating. 883 */ 884 @JsxFunction 885 public void stopPropagation() { 886 stopPropagation_ = true; 887 } 888 889 /** 890 * Indicates if event propagation is stopped. 891 * @return the status 892 */ 893 public boolean isPropagationStopped() { 894 return stopPropagation_; 895 } 896 897 /** 898 * Prevents other listeners of the same event from being called. 899 */ 900 @JsxFunction 901 public void stopImmediatePropagation() { 902 stopImmediatePropagation_ = true; 903 stopPropagation(); 904 } 905 906 /** 907 * Indicates if event immediate propagation is stopped. 908 * @return the status 909 */ 910 public boolean isImmediatePropagationStopped() { 911 return stopImmediatePropagation_; 912 } 913 914 /** 915 * Handles the return values of property handlers. 916 * @param returnValue the return value returned by the property handler 917 */ 918 void handlePropertyHandlerReturnValue(final Object returnValue) { 919 if (Boolean.FALSE.equals(returnValue)) { 920 preventDefault(); 921 } 922 } 923 924 /** 925 * Returns the property name associated with the event. 926 * @return the property name associated with the event 927 */ 928 public String getPropertyName() { 929 return propertyName_; 930 } 931 932 /** 933 * Initializes this event. 934 * @param type the event type 935 * @param bubbles whether or not the event should bubble 936 * @param cancelable whether or not the event the event should be cancelable 937 */ 938 @JsxFunction 939 public void initEvent(final String type, final boolean bubbles, final boolean cancelable) { 940 type_ = type; 941 bubbles_ = bubbles; 942 cancelable_ = cancelable; 943 } 944 945 /** 946 * If, during any stage of event flow, this method is called the event is canceled. 947 * Any default action associated with the event will not occur. 948 * Calling this method for a non-cancelable event has no effect. 949 */ 950 @JsxFunction 951 public void preventDefault() { 952 if (isCancelable()) { 953 preventDefault_ = true; 954 } 955 } 956 957 /** 958 * Returns {@code true} if this event has been aborted via <code>preventDefault()</code> in 959 * standards-compliant browsers. 960 * 961 * @param result the event handler result (if {@code false}, the event is considered aborted) 962 * @return {@code true} if this event has been aborted 963 */ 964 public boolean isAborted(final ScriptResult result) { 965 return ScriptResult.isFalse(result) || preventDefault_; 966 } 967 968 /** 969 * {@inheritDoc} 970 */ 971 @Override 972 public String toString() { 973 final StringBuilder builder = new StringBuilder(40); 974 builder.append("Event ") 975 .append(getType()) 976 .append(" (Current Target: ") 977 .append(currentTarget_) 978 .append(");"); 979 return builder.toString(); 980 } 981 982 /** 983 * <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br> 984 * 985 * If we click on a label, we have to simulate a click on the element referenced by the 'for' attribute also. 986 * To support this for special events we have this method here. 987 * @return false in this default impl 988 */ 989 public boolean processLabelAfterBubbling() { 990 return false; 991 } 992 993 /** 994 * @return the return value property 995 */ 996 @JsxGetter 997 public Object getReturnValue() { 998 return !preventDefault_; 999 } 1000 1001 /** 1002 * @param newValue the new return value 1003 */ 1004 @JsxSetter 1005 public void setReturnValue(final Object newValue) { 1006 if (isCancelable()) { 1007 final boolean bool = !JavaScriptEngine.toBoolean(newValue); 1008 if (bool) { 1009 preventDefault_ = bool; 1010 } 1011 } 1012 } 1013 1014 /** 1015 * @return the return composed property 1016 */ 1017 @JsxGetter 1018 public boolean getComposed() { 1019 return false; 1020 } 1021 1022 /** 1023 * Returns whether the given value indicates a missing or undefined property. 1024 * @param value the new value 1025 * @return whether the given value indicates a missing or undefined property 1026 */ 1027 protected static boolean isMissingOrUndefined(final Object value) { 1028 return value == Scriptable.NOT_FOUND || JavaScriptEngine.isUndefined(value); 1029 } 1030 }