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.worker;
16  
17  import org.htmlunit.WebClient;
18  import org.htmlunit.corejs.javascript.Context;
19  import org.htmlunit.corejs.javascript.Function;
20  import org.htmlunit.corejs.javascript.Scriptable;
21  import org.htmlunit.corejs.javascript.VarScope;
22  import org.htmlunit.javascript.JavaScriptEngine;
23  import org.htmlunit.javascript.configuration.JsxClass;
24  import org.htmlunit.javascript.configuration.JsxConstructor;
25  import org.htmlunit.javascript.configuration.JsxFunction;
26  import org.htmlunit.javascript.configuration.JsxGetter;
27  import org.htmlunit.javascript.configuration.JsxSetter;
28  import org.htmlunit.javascript.host.Window;
29  import org.htmlunit.javascript.host.event.Event;
30  import org.htmlunit.javascript.host.event.EventTarget;
31  
32  /**
33   * JavaScript host object for {@code Worker}.
34   *
35   * @author Ahmed Ashour
36   * @author Marc Guillemot
37   * @author Ronald Brill
38   *
39   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker">MDN Documentation</a>
40   */
41  @JsxClass
42  public class Worker extends EventTarget {
43  
44      private final DedicatedWorkerGlobalScope workerScope_;
45  
46      /**
47       * Default constructor.
48       */
49      public Worker() {
50          // prototype constructor
51          super();
52          workerScope_ = null;
53      }
54  
55      private Worker(final Context cx, final VarScope scope,
56                      final Window owningWindow, final String url,
57                      final Scriptable options) throws Exception {
58          super();
59          setParentScope(scope);
60          setPrototype(getPrototype(getClass()));
61  
62          final WebClient webClient = getWindow().getWebWindow().getWebClient();
63          String name = null;
64          if (options != null && options.has("name", options)) {
65              name = JavaScriptEngine.toString(options.get("name", options));
66          }
67          workerScope_ = new DedicatedWorkerGlobalScope(owningWindow, cx, webClient, name, this);
68  
69          workerScope_.loadAndExecute(webClient, url, null, false);
70      }
71  
72      /**
73       * Creates an instance of this object.
74       *
75       * @param cx the current context
76       * @param scope the scope
77       * @param args the constructor arguments
78       * @param ctorObj the function object
79       * @param inNewExpr whether invoked via {@code new}
80       * @return the new {@code Worker} instance
81       * @throws Exception in case of problem
82       */
83      @JsxConstructor
84      public static Worker jsConstructor(final Context cx, final VarScope scope,
85              final Object[] args, final Function ctorObj, final boolean inNewExpr) throws Exception {
86          if (args.length < 1 || args.length > 2) {
87              throw JavaScriptEngine.reportRuntimeError(
88                      "Worker Error: constructor must have one or two parameters.");
89          }
90  
91          final String url = JavaScriptEngine.toString(args[0]);
92          Scriptable options = null;
93          if (args.length > 1 && args[1] instanceof Scriptable scriptable) {
94              options = scriptable;
95          }
96          return new Worker(cx, scope, getWindow(ctorObj), url, options);
97      }
98  
99      /**
100      * Posts the provided message to the worker's execution context.
101      *
102      * @param message the message to post
103      */
104     @JsxFunction
105     public void postMessage(final Object message) {
106         workerScope_.messagePosted(message);
107     }
108 
109     /**
110      * Immediately terminates the worker without giving it the opportunity to
111      * finish any currently executing operations.
112      */
113     @JsxFunction
114     public void terminate() {
115         // TODO
116     }
117 
118     /**
119      * Sets the {@code onmessage} event handler.
120      *
121      * @param onmessage the new {@code onmessage} event handler
122      */
123     @JsxSetter
124     public void setOnmessage(final Object onmessage) {
125         getEventListenersContainer().setEventHandler(Event.TYPE_MESSAGE, onmessage);
126     }
127 
128     /**
129      * Returns the {@code onmessage} event handler.
130      *
131      * @return the {@code onmessage} event handler
132      */
133     @JsxGetter
134     public Function getOnmessage() {
135         return getEventListenersContainer().getEventHandler(Event.TYPE_MESSAGE);
136     }
137 }