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.HttpHeader;
18  import org.htmlunit.corejs.javascript.NativeArray;
19  import org.htmlunit.corejs.javascript.Scriptable;
20  import org.htmlunit.corejs.javascript.ScriptableObject;
21  import org.htmlunit.javascript.JavaScriptEngine;
22  import org.htmlunit.javascript.configuration.JsxClass;
23  import org.htmlunit.javascript.configuration.JsxConstructor;
24  import org.htmlunit.javascript.configuration.JsxFunction;
25  import org.htmlunit.javascript.configuration.JsxGetter;
26  import org.htmlunit.javascript.host.Window;
27  import org.htmlunit.javascript.host.WindowProxy;
28  
29  /**
30   * A JavaScript object for {@code MessageEvent}.
31   * <p>
32   * For general information on which properties and functions should be supported, see
33   * <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#messageevent">
34   * Event definitions</a>.
35   * </p>
36   *
37   * @see <a href="https://developer.mozilla.org/en/WebSockets/WebSockets_reference/MessageEvent">
38   *          Mozilla documentation</a>
39   * @author Ahmed Ashour
40   * @author Frank Danek
41   * @author Ronald Brill
42   */
43  @JsxClass
44  public class MessageEvent extends Event {
45  
46      private Object data_;
47      private String origin_;
48      private String lastEventId_;
49      private Window source_;
50      private Object ports_;
51  
52      /**
53       * Default constructor used to build the prototype.
54       */
55      public MessageEvent() {
56          super();
57          setType(TYPE_MESSAGE);
58          origin_ = "";
59          lastEventId_ = "";
60          data_ = JavaScriptEngine.UNDEFINED;
61      }
62  
63      /**
64       * Constructs a Message Event with the provided data.
65       * @param data the data
66       */
67      public MessageEvent(final Object data) {
68          this();
69          data_ = data;
70      }
71  
72      /**
73       * JavaScript constructor.
74       *
75       * @param type the event type
76       * @param details the event details (optional)
77       */
78      @Override
79      @JsxConstructor
80      public void jsConstructor(final String type, final ScriptableObject details) {
81          super.jsConstructor(type, details);
82  
83          data_ = null;
84  
85          String origin = "";
86          String lastEventId = "";
87          if (details != null && !JavaScriptEngine.isUndefined(details)) {
88              data_ = details.get("data");
89  
90              final String detailOrigin = (String) details.get(HttpHeader.ORIGIN_LC);
91              if (detailOrigin != null) {
92                  origin = detailOrigin;
93              }
94  
95              final Object detailLastEventId = details.get("lastEventId");
96              if (detailLastEventId != null) {
97                  lastEventId = JavaScriptEngine.toString(detailLastEventId);
98              }
99  
100             source_ = null;
101             final Object detailSource = details.get("source");
102             if (detailSource instanceof Window window) {
103                 source_ = window;
104             }
105             else if (detailSource instanceof WindowProxy proxy) {
106                 source_ = proxy.getDelegee();
107             }
108             ports_ = details.get("ports");
109         }
110         origin_ = origin;
111         lastEventId_ = lastEventId;
112     }
113 
114     /**
115      * Initializes an event object.
116      * @param type the event type
117      * @param canBubble can the event bubble
118      * @param cancelable can the event be canceled
119      * @param data the message
120      * @param origin the scheme, hostname and port of the document that caused the event
121      * @param lastEventId the identifier of the last event
122      * @param source the window object that contains the document that caused the event
123      * @param ports the message ports
124      */
125     @JsxFunction
126     public void initMessageEvent(
127             final String type,
128             final boolean canBubble,
129             final boolean cancelable,
130             final Object data,
131             final String origin,
132             final String lastEventId,
133             final Window source,
134             final Object ports) {
135         initEvent(type, canBubble, cancelable);
136         data_ = data;
137         origin_ = origin;
138         lastEventId_ = lastEventId;
139         source_ = source;
140 
141         if (JavaScriptEngine.isUndefined(ports)
142             || ports instanceof NativeArray
143             || (ports instanceof Scriptable scriptable && ScriptableObject.hasProperty(scriptable, "length"))) {
144             ports_ = ports;
145         }
146         else {
147             throw JavaScriptEngine.typeError(
148                     "Argument 8 of MessageEvent.initMessageEvent can't be converted to a sequence.");
149         }
150     }
151 
152     /**
153      * Retrieves the data contained.
154      * @return the data contained
155      */
156     @JsxGetter
157     public Object getData() {
158         return data_;
159     }
160 
161     /**
162      * Gets the URI of the document of origin.
163      * @return the origin
164      */
165     @JsxGetter
166     public String getOrigin() {
167         return origin_;
168     }
169 
170     /**
171      * Sets the URI of the document of origin.
172      * @param origin the origin
173      */
174     public void setOrigin(final String origin) {
175         origin_ = origin;
176     }
177 
178     /**
179      * Retrieves the identifier of the last event.
180      * @return the identified of the last event
181      */
182     @JsxGetter
183     public String getLastEventId() {
184         return lastEventId_;
185     }
186 
187     /**
188      * Retrieves the data contained.
189      * @return the data contained
190      */
191     @JsxGetter
192     public Window getSource() {
193         return source_;
194     }
195 
196     /**
197      * Returns the {@code ports} property.
198      * @return the {@code ports} property
199      */
200     @JsxGetter
201     public Object getPorts() {
202         return ports_;
203     }
204 }