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.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 object representing the BeforeUnloadEvent.
27 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/window.onbeforeunload">Mozilla Developer Network</a>
28 * @see <a href="http://msdn.microsoft.com/en-us/library/ie/ff974336.aspx">MSDN</a>
29 *
30 * @author Frank Danek
31 * @author Ahmed Ashour
32 * @author Ronald Brill
33 * @author Atsushi Nakagawa
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 * The JavaScript constructor. It seems it is not possible to do it from JavaScript code.
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 * @return {@code true} if returnValue holds the beforeunload message
82 */
83 public boolean isBeforeUnloadMessageSet() {
84 return !getReturnValueDefault(getBrowserVersion()).equals(getReturnValue());
85 }
86
87 /**
88 * @return the return value associated with the event
89 */
90 @JsxGetter
91 @Override
92 public Object getReturnValue() {
93 return returnValue_;
94 }
95
96 /**
97 * Sets the return value associated with the event.
98 * @param returnValue the return value associated with the event
99 */
100 @JsxSetter
101 @Override
102 public void setReturnValue(final Object returnValue) {
103 returnValue_ = returnValue;
104 }
105
106 @Override
107 void handlePropertyHandlerReturnValue(final Object returnValue) {
108 super.handlePropertyHandlerReturnValue(returnValue);
109
110 final BrowserVersion browserVersion = getBrowserVersion();
111
112 // Most browsers ignore null return values of property handlers
113 if (returnValue != null) {
114 // Chrome/Firefox only accept the return value if returnValue is equal to default
115 if (getReturnValueDefault(browserVersion).equals(getReturnValue())) {
116 setReturnValue(returnValue);
117 }
118 }
119 }
120 }