Skip to content

Commit 486e8bc

Browse files
committed
support dedicated scopeConfiguration
1 parent ab5f6cd commit 486e8bc

File tree

8 files changed

+169
-53
lines changed

8 files changed

+169
-53
lines changed

src/main/java/org/htmlunit/javascript/JavaScriptEngine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ private void init(final WebWindow webWindow, final Page page, final Context cont
219219
final Map<Class<? extends Scriptable>, Scriptable> prototypes = new HashMap<>();
220220
final Map<String, Scriptable> prototypesPerJSName = new HashMap<>();
221221

222-
final ClassConfiguration windowConfig = jsConfig_.getClassConfiguration("Window");
222+
final ClassConfiguration windowConfig = jsConfig_.getWindowClassConfiguration();
223223
final FunctionObject functionObject = new RecursiveFunctionObject(jsWindowScope.getClassName(),
224224
windowConfig.getJsConstructor().getValue(), jsWindowScope, browserVersion);
225225
ScriptableObject.defineProperty(jsWindowScope, "constructor", functionObject,

src/main/java/org/htmlunit/javascript/configuration/AbstractJavaScriptConfiguration.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.lang.reflect.Method;
2525
import java.util.ArrayList;
2626
import java.util.HashSet;
27-
import java.util.List;
2827
import java.util.Map;
2928
import java.util.Map.Entry;
3029
import java.util.Set;
@@ -53,18 +52,23 @@ public abstract class AbstractJavaScriptConfiguration {
5352
private Map<Class<?>, Class<? extends HtmlUnitScriptable>> domJavaScriptMap_;
5453

5554
private final ArrayList<ClassConfiguration> configuration_;
55+
private ClassConfiguration scopeConfiguration_;
5656

5757
/**
5858
* Constructor.
5959
* @param browser the browser version to use
60+
* @param scopeClass the scope class for faster access
6061
*/
61-
protected AbstractJavaScriptConfiguration(final BrowserVersion browser) {
62+
protected AbstractJavaScriptConfiguration(final BrowserVersion browser, final Class<?> scopeClass) {
6263
configuration_ = new ArrayList<>(getClasses().length);
6364

6465
for (final Class<? extends HtmlUnitScriptable> klass : getClasses()) {
6566
final ClassConfiguration config = getClassConfiguration(klass, browser);
6667
if (config != null) {
6768
configuration_.add(config);
69+
if (klass == scopeClass) {
70+
scopeConfiguration_ = config;
71+
}
6872
}
6973
}
7074
}
@@ -421,4 +425,8 @@ public Class<? extends HtmlUnitScriptable> getDomJavaScriptMappingFor(final Clas
421425

422426
return domJavaScriptMap_.get(clazz);
423427
}
428+
429+
protected ClassConfiguration getScopeConfiguration() {
430+
return scopeConfiguration_;
431+
}
424432
}

src/main/java/org/htmlunit/javascript/configuration/JavaScriptConfiguration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
696696
* @param browser the browser version to use
697697
*/
698698
private JavaScriptConfiguration(final BrowserVersion browser) {
699-
super(browser);
699+
super(browser, Window.class);
700700
}
701701

702702
/**
@@ -723,4 +723,11 @@ public static synchronized JavaScriptConfiguration getInstance(final BrowserVers
723723
protected Class<? extends HtmlUnitScriptable>[] getClasses() {
724724
return CLASSES_;
725725
}
726+
727+
/**
728+
* @return the configuration of the scope class
729+
*/
730+
public ClassConfiguration getWindowClassConfiguration() {
731+
return getScopeConfiguration();
732+
}
726733
}

src/main/java/org/htmlunit/javascript/configuration/ProxyAutoConfigJavaScriptConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public final class ProxyAutoConfigJavaScriptConfiguration extends AbstractJavaSc
4040
* @param browser the browser version to use
4141
*/
4242
private ProxyAutoConfigJavaScriptConfiguration(final BrowserVersion browser) {
43-
super(browser);
43+
super(browser, ProxyAutoConfig.class);
4444
}
4545

4646
/**

src/main/java/org/htmlunit/javascript/configuration/WorkerJavaScriptConfiguration.java

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -138,39 +138,34 @@ public final class WorkerJavaScriptConfiguration extends AbstractJavaScriptConfi
138138

139139
@SuppressWarnings("unchecked")
140140
static final Class<? extends HtmlUnitScriptable>[] CLASSES_ = new Class[] {
141-
AbortController.class, AbortSignal.class, Atomics.class,
142-
Blob.class, BroadcastChannel.class,
143-
Cache.class, CacheStorage.class, CanvasGradient.class, CanvasPattern.class,
144-
ClientRect.class, CloseEvent.class,
145-
Crypto.class, CryptoKey.class, CustomEvent.class,
146-
DedicatedWorkerGlobalScope.class, DOMException.class, DOMMatrix.class, DOMMatrixReadOnly.class,
147-
DOMPoint.class, DOMPointReadOnly.class, DOMRectReadOnly.class, DOMStringList.class,
148-
ErrorEvent.class, Event.class, EventSource.class, EventTarget.class,
149-
File.class, FileList.class, FileReader.class,
150-
FontFace.class, FontFaceSet.class, FormData.class,
151-
Headers.class,
152-
IDBCursor.class, IDBCursorWithValue.class, IDBDatabase.class, IDBFactory.class, IDBIndex.class,
153-
IDBKeyRange.class, IDBObjectStore.class, IDBOpenDBRequest.class, IDBRequest.class, IDBTransaction.class,
154-
IDBVersionChangeEvent.class, ImageBitmap.class, ImageBitmapRenderingContext.class, ImageData.class,
155-
MediaSource.class, MessageChannel.class, MessageEvent.class, MessagePort.class,
156-
NetworkInformation.class, Notification.class,
157-
Path2D.class, Performance.class, PerformanceEntry.class, PerformanceMark.class, PerformanceMeasure.class,
158-
PerformanceObserver.class, PerformanceObserverEntryList.class, PerformanceResourceTiming.class,
159-
PeriodicSyncManager.class, Permissions.class, PermissionStatus.class,
160-
ProgressEvent.class, PromiseRejectionEvent.class,
161-
PushManager.class, PushSubscription.class, PushSubscriptionOptions.class,
162-
ReadableStream.class, Request.class, Response.class,
163-
SecurityPolicyViolationEvent.class, ServiceWorkerRegistration.class, SourceBuffer.class, SourceBufferList.class,
164-
StorageManager.class, SubtleCrypto.class, SyncManager.class,
165-
TextDecoder.class, TextEncoder.class, TextMetrics.class,
166-
URL.class, URLSearchParams.class,
167-
WebGLContextEvent.class, WebGL2RenderingContext.class, WebGLActiveInfo.class, WebGLBuffer.class,
168-
WebGLFramebuffer.class, WebGLProgram.class, WebGLQuery.class,
169-
WebGLRenderbuffer.class, WebGLRenderingContext.class,
170-
WebGLSampler.class, WebGLShader.class, WebGLShaderPrecisionFormat.class, WebGLSync.class, WebGLTexture.class,
171-
WebGLTransformFeedback.class, WebGLUniformLocation.class, WebGLVertexArrayObject.class, WebSocket.class,
172-
Worker.class, WorkerGlobalScope.class, WorkerLocation.class, WorkerNavigator.class,
173-
XMLHttpRequest.class, XMLHttpRequestEventTarget.class, XMLHttpRequestUpload.class
141+
// level 1
142+
AbortController.class, Atomics.class, Blob.class, Cache.class, CacheStorage.class, CanvasGradient.class,
143+
CanvasPattern.class, ClientRect.class, Crypto.class, CryptoKey.class, DOMException.class,
144+
DOMMatrixReadOnly.class, DOMPointReadOnly.class, DOMRectReadOnly.class, DOMStringList.class,
145+
Event.class, EventTarget.class, FileList.class, FontFace.class, FormData.class, Headers.class,
146+
IDBCursor.class, IDBFactory.class, IDBIndex.class, IDBKeyRange.class, IDBObjectStore.class,
147+
ImageBitmap.class, ImageBitmapRenderingContext.class, ImageData.class, MessageChannel.class,
148+
Path2D.class, PerformanceEntry.class, PerformanceObserver.class, PerformanceObserverEntryList.class,
149+
PeriodicSyncManager.class, Permissions.class, PushManager.class, PushSubscription.class,
150+
PushSubscriptionOptions.class, ReadableStream.class, Request.class, Response.class, StorageManager.class,
151+
SubtleCrypto.class, SyncManager.class, TextDecoder.class, TextEncoder.class, TextMetrics.class,
152+
URL.class, URLSearchParams.class, WebGL2RenderingContext.class, WebGLActiveInfo.class, WebGLBuffer.class,
153+
WebGLFramebuffer.class, WebGLProgram.class, WebGLQuery.class, WebGLRenderbuffer.class,
154+
WebGLRenderingContext.class, WebGLSampler.class, WebGLShader.class, WebGLShaderPrecisionFormat.class,
155+
WebGLSync.class, WebGLTexture.class, WebGLTransformFeedback.class, WebGLUniformLocation.class,
156+
WebGLVertexArrayObject.class, WorkerLocation.class, WorkerNavigator.class,
157+
// level 2
158+
AbortSignal.class, BroadcastChannel.class, CloseEvent.class, CustomEvent.class, DOMMatrix.class,
159+
DOMPoint.class, ErrorEvent.class, EventSource.class, File.class, FileReader.class, FontFaceSet.class,
160+
IDBCursorWithValue.class, IDBDatabase.class, IDBRequest.class, IDBTransaction.class,
161+
IDBVersionChangeEvent.class, MediaSource.class, MessageEvent.class, MessagePort.class,
162+
NetworkInformation.class, Notification.class, Performance.class, PerformanceMark.class,
163+
PerformanceMeasure.class, PerformanceResourceTiming.class, PermissionStatus.class, ProgressEvent.class,
164+
PromiseRejectionEvent.class, SecurityPolicyViolationEvent.class, ServiceWorkerRegistration.class,
165+
SourceBuffer.class, SourceBufferList.class, WebGLContextEvent.class, WebSocket.class, Worker.class,
166+
WorkerGlobalScope.class, XMLHttpRequestEventTarget.class,
167+
// level 3
168+
DedicatedWorkerGlobalScope.class, IDBOpenDBRequest.class, XMLHttpRequest.class, XMLHttpRequestUpload.class,
174169
};
175170

176171
/** Cache of browser versions and their corresponding JavaScript configurations. */
@@ -181,7 +176,7 @@ public final class WorkerJavaScriptConfiguration extends AbstractJavaScriptConfi
181176
* @param browser the browser version to use
182177
*/
183178
private WorkerJavaScriptConfiguration(final BrowserVersion browser) {
184-
super(browser);
179+
super(browser, DedicatedWorkerGlobalScope.class);
185180
}
186181

187182
/**
@@ -208,4 +203,11 @@ public static synchronized WorkerJavaScriptConfiguration getInstance(final Brows
208203
protected Class<? extends HtmlUnitScriptable>[] getClasses() {
209204
return CLASSES_;
210205
}
206+
207+
/**
208+
* @return the configuration of the scope class
209+
*/
210+
public ClassConfiguration getDedicatedWorkerGlobalScopeClassConfiguration() {
211+
return getScopeConfiguration();
212+
}
211213
}

src/main/java/org/htmlunit/javascript/host/worker/DedicatedWorkerGlobalScope.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,8 @@ public void jsConstructor() {
136136

137137
final WorkerJavaScriptConfiguration jsConfig = WorkerJavaScriptConfiguration.getInstance(browserVersion);
138138

139-
ClassConfiguration config = jsConfig.getClassConfiguration(
140-
DedicatedWorkerGlobalScope.class.getSuperclass().getSimpleName());
141-
final HtmlUnitScriptable parentPrototype = JavaScriptEngine.configureClass(config, this);
142-
143-
config = jsConfig.getClassConfiguration(DedicatedWorkerGlobalScope.class.getSimpleName());
139+
final ClassConfiguration config = jsConfig.getDedicatedWorkerGlobalScopeClassConfiguration();
144140
final HtmlUnitScriptable prototype = JavaScriptEngine.configureClass(config, this);
145-
prototype.setPrototype(parentPrototype);
146141
setPrototype(prototype);
147142

148143
final Map<Class<? extends Scriptable>, Scriptable> prototypes = new HashMap<>();

src/test/java/org/htmlunit/javascript/configuration/JavaScriptConfigurationTest.java

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import java.net.URL;
2727
import java.text.MessageFormat;
2828
import java.util.ArrayList;
29+
import java.util.Collections;
2930
import java.util.Enumeration;
31+
import java.util.HashMap;
3032
import java.util.List;
3133
import java.util.Locale;
3234
import java.util.Map;
@@ -42,6 +44,7 @@
4244
import org.htmlunit.WebTestCase;
4345
import org.htmlunit.javascript.HtmlUnitScriptable;
4446
import org.htmlunit.javascript.JavaScriptEngine;
47+
import org.junit.Assert;
4548
import org.junit.Test;
4649

4750
/**
@@ -262,19 +265,45 @@ public void obsoleteJsxClasses() {
262265
}
263266

264267
/**
265-
* Test of alphabetical order.
268+
* Test of order.
266269
*/
267270
@Test
268-
public void lexicographicOrder() {
269-
String lastClassName = null;
271+
public void treeOrder() {
272+
final List<String> defined = new ArrayList<>(JavaScriptConfiguration.CLASSES_.length);
273+
274+
final HashMap<Integer, List<String>> levels = new HashMap<>();
270275
for (final Class<?> c : JavaScriptConfiguration.CLASSES_) {
271-
final String name = c.getSimpleName();
272-
if (lastClassName != null && name.compareToIgnoreCase(lastClassName) < 0) {
273-
fail("JavaScriptConfiguration.CLASSES_: '"
274-
+ name + "' should be before '" + lastClassName + "'");
276+
defined.add(c.getSimpleName());
277+
278+
int level = 1;
279+
Class<?> parent = c.getSuperclass();
280+
while (parent != HtmlUnitScriptable.class) {
281+
level++;
282+
parent = parent.getSuperclass();
283+
}
284+
285+
List<String> clsAtLevel = levels.get(level);
286+
if (clsAtLevel == null) {
287+
clsAtLevel = new ArrayList<>();
288+
levels.put(level, clsAtLevel);
275289
}
276-
lastClassName = name;
290+
clsAtLevel.add(c.getSimpleName());
291+
}
292+
293+
final List<String> all = new ArrayList<>(JavaScriptConfiguration.CLASSES_.length);
294+
for (int level = 1; level <= levels.size(); level++) {
295+
final List<String> clsAtLevel = levels.get(level);
296+
Collections.sort(clsAtLevel);
297+
all.addAll(clsAtLevel);
298+
299+
// dump
300+
// System.out.println("// level " + level);
301+
// for (String cls : clsAtLevel) {
302+
// System.out.print(cls + ".class, ");
303+
// }
304+
// System.out.println();
277305
}
306+
Assert.assertEquals(all, defined);
278307
}
279308

280309
/**
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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.configuration;
16+
17+
import java.util.ArrayList;
18+
import java.util.Collections;
19+
import java.util.HashMap;
20+
import java.util.List;
21+
22+
import org.htmlunit.javascript.HtmlUnitScriptable;
23+
import org.junit.Assert;
24+
import org.junit.Test;
25+
26+
/**
27+
* Tests for {@link WorkerJavaScriptConfiguration}.
28+
*
29+
* @author Ronald Brill
30+
*/
31+
public class WorkerJavaScriptConfigurationTest {
32+
33+
34+
/**
35+
* Test of order.
36+
*/
37+
@Test
38+
public void treeOrder() {
39+
final List<String> defined = new ArrayList<>(JavaScriptConfiguration.CLASSES_.length);
40+
41+
final HashMap<Integer, List<String>> levels = new HashMap<>();
42+
for (final Class<?> c : JavaScriptConfiguration.CLASSES_) {
43+
defined.add(c.getSimpleName());
44+
45+
int level = 1;
46+
Class<?> parent = c.getSuperclass();
47+
while (parent != HtmlUnitScriptable.class) {
48+
level++;
49+
parent = parent.getSuperclass();
50+
}
51+
52+
List<String> clsAtLevel = levels.get(level);
53+
if (clsAtLevel == null) {
54+
clsAtLevel = new ArrayList<>();
55+
levels.put(level, clsAtLevel);
56+
}
57+
clsAtLevel.add(c.getSimpleName());
58+
}
59+
60+
final List<String> all = new ArrayList<>(JavaScriptConfiguration.CLASSES_.length);
61+
for (int level = 1; level <= levels.size(); level++) {
62+
final List<String> clsAtLevel = levels.get(level);
63+
Collections.sort(clsAtLevel);
64+
all.addAll(clsAtLevel);
65+
66+
// dump
67+
// System.out.println("// level " + level);
68+
// for (String cls : clsAtLevel) {
69+
// System.out.print(cls + ".class, ");
70+
// }
71+
// System.out.println();
72+
}
73+
Assert.assertEquals(all, defined);
74+
}
75+
}

0 commit comments

Comments
 (0)