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.BrowserVersion;
18 import org.htmlunit.html.DomNode;
19 import org.htmlunit.javascript.JavaScriptEngine;
20 import org.htmlunit.javascript.configuration.JsxClass;
21 import org.htmlunit.javascript.configuration.JsxConstructor;
22 import org.htmlunit.javascript.configuration.JsxGetter;
23 import org.htmlunit.javascript.configuration.JsxSetter;
24
25 /**
26 * JavaScript host object for {@code BeforeUnloadEvent}.
27 *
28 * @author Frank Danek
29 * @author Ahmed Ashour
30 * @author Ronald Brill
31 * @author Atsushi Nakagawa
32 *
33 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/BeforeUnloadEvent">MDN Documentation</a>
34 */
35 @JsxClass
36 public class BeforeUnloadEvent extends Event {
37 private Object returnValue_;
38
39 /**
40 * Creates a new event instance.
41 */
42 public BeforeUnloadEvent() {
43 super("");
44 returnValue_ = "";
45 }
46
47 /**
48 * JavaScript constructor. This event cannot be constructed from JavaScript.
49 */
50 @JsxConstructor
51 public void jsConstructor() {
52 throw JavaScriptEngine.typeError("Illegal Constructor");
53 }
54
55 /**
56 * Creates a new event instance.
57 *
58 * @param domNode the DOM node that triggered the event
59 * @param type the event type
60 */
61 public BeforeUnloadEvent(final DomNode domNode, final String type) {
62 super(domNode, type);
63
64 setBubbles(false);
65 setReturnValue(getReturnValueDefault(getBrowserVersion()));
66 }
67
68 @Override
69 public void initEvent(final String type, final boolean bubbles, final boolean cancelable) {
70 super.initEvent(type, bubbles, cancelable);
71 setReturnValue(getReturnValueDefault(getBrowserVersion()));
72 }
73
74 private static Object getReturnValueDefault(final BrowserVersion browserVersion) {
75 // Empty string default is specified by HTML5
76 // https://www.w3.org/TR/html5/browsers.html#the-beforeunloadevent-interface
77 return "";
78 }
79
80 /**
81 * Returns {@code true} if {@code returnValue} holds the beforeunload message.
82 *
83 * @return {@code true} if {@code returnValue} holds the beforeunload message
84 */
85 public boolean isBeforeUnloadMessageSet() {
86 return !getReturnValueDefault(getBrowserVersion()).equals(getReturnValue());
87 }
88
89 /**
90 * Returns the return value associated with the event.
91 *
92 * @return the return value associated with the event
93 */
94 @JsxGetter
95 @Override
96 public Object getReturnValue() {
97 return returnValue_;
98 }
99
100 /**
101 * Sets the return value associated with the event.
102 *
103 * @param returnValue the return value associated with the event
104 */
105 @JsxSetter
106 @Override
107 public void setReturnValue(final Object returnValue) {
108 returnValue_ = returnValue;
109 }
110
111 @Override
112 void handlePropertyHandlerReturnValue(final Object returnValue) {
113 super.handlePropertyHandlerReturnValue(returnValue);
114
115 final BrowserVersion browserVersion = getBrowserVersion();
116
117 // Most browsers ignore null return values of property handlers
118 if (returnValue != null) {
119 // Chrome/Firefox only accept the return value if returnValue is equal to default
120 if (getReturnValueDefault(browserVersion).equals(getReturnValue())) {
121 setReturnValue(returnValue);
122 }
123 }
124 }
125 }