Skip to content

Commit 93635fa

Browse files
committed
support array-likes
1 parent a8a5447 commit 93635fa

3 files changed

Lines changed: 35 additions & 22 deletions

File tree

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.htmlunit.WebAssert;
3737
import org.htmlunit.WebClient;
3838
import org.htmlunit.WebWindow;
39+
import org.htmlunit.corejs.javascript.AbstractEcmaObjectOperations;
3940
import org.htmlunit.corejs.javascript.Callable;
4041
import org.htmlunit.corejs.javascript.Context;
4142
import org.htmlunit.corejs.javascript.ContextAction;
@@ -1425,6 +1426,23 @@ public static boolean isArray(final Object obj) {
14251426
&& "Array".equals(s.getClassName());
14261427
}
14271428

1429+
/**
1430+
* @param obj the value to check
1431+
* @return true if the passed in {@link Scriptable} looks like an array
1432+
*/
1433+
public static boolean isArrayLike(final Scriptable obj) {
1434+
return ScriptRuntime.isArrayLike(obj);
1435+
}
1436+
1437+
/**
1438+
* @param cx the Context
1439+
* @param obj the value to check
1440+
* @return the length of the array like {@link Scriptable}
1441+
*/
1442+
public static long lengthOfArrayLike(final Context cx, final Scriptable obj) {
1443+
return AbstractEcmaObjectOperations.lengthOfArrayLike(cx, obj);
1444+
}
1445+
14281446
/**
14291447
* @return the top call scope
14301448
*/

src/main/java/org/htmlunit/javascript/host/intl/Intl.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,13 @@ public static Object getCanonicalLocales(final Context cx, final Scriptable this
139139
languageTags.add(s);
140140
}
141141
else if (localesArgument instanceof Scriptable scriptable) {
142-
if ("String".equals(scriptable.getClassName()) || scriptable instanceof Locale) {
143-
languageTags.add(scriptable.toString());
144-
}
145-
else if (scriptable instanceof NativeArray array) {
146-
for (int i = 0; i < array.getLength(); i++) {
147-
final Object elem = array.get(i);
142+
if (JavaScriptEngine.isArrayLike(scriptable)) {
143+
final long len = JavaScriptEngine.lengthOfArrayLike(cx, scriptable);
144+
for (int i = 0; i < len; i++) {
145+
final Object elem = scriptable.get(i, scriptable);
148146
if (elem instanceof String s) {
149147
languageTags.add(s);
150148
}
151-
else if (elem instanceof Locale) {
152-
languageTags.add(elem.toString());
153-
}
154149
else if (elem instanceof ScriptableObject) {
155150
languageTags.add(JavaScriptEngine.toString(elem));
156151
}
@@ -171,7 +166,7 @@ else if (elem instanceof ScriptableObject) {
171166
new java.util.Locale.Builder().setLanguageTag(tag).build().toLanguageTag());
172167
}
173168
catch (final IllformedLocaleException e) {
174-
throw JavaScriptEngine.rangeError("Invalid language tag: " + tag);
169+
throw JavaScriptEngine.rangeError("Invalid language tag: '" + tag + "'");
175170
}
176171
}
177172

@@ -198,7 +193,7 @@ static Scriptable supportedLocalesOf(final Scriptable localesArgument) {
198193
final List<String> supportedLocales = new ArrayList<>();
199194
for (final String locale : locales) {
200195
if (locale.isEmpty()) {
201-
throw JavaScriptEngine.rangeError("Invalid language tag: " + locale);
196+
throw JavaScriptEngine.rangeError("Invalid language tag: '" + locale + "'");
202197
}
203198
final java.util.Locale l = java.util.Locale.forLanguageTag(locale);
204199
if (LocaleUtils.isAvailableLocale(l)) {

src/test/java/org/htmlunit/javascript/host/intl/IntlTest.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,24 @@ public void v8BreakIterator() throws Exception {
104104
* @throws Exception if the test fails
105105
*/
106106
@Test
107-
@Alerts({"en-US", "en-US,fr-FR,ja-JP",
108-
"zh-Hant-TW", "en-Latn-US",
109-
"ja-JP", "en-US,fr", "en-US", "ja-JP",
107+
@Alerts({"en-US", "en-US,fr-FR,ja-JP", "zh-Hant-TW", "en-Latn-US",
108+
"ja-JP", "en-US,fr", "en-US", "RangeError", "ja-JP",
110109
"TypeError", "", "", "RangeError", "RangeError", ""})
111110
public void getCanonicalLocales() throws Exception {
112111
final String html = DOCTYPE_HTML
113112
+ "<html><head>\n"
114113
+ "<script>\n"
115114
+ LOG_TITLE_FUNCTION
116115
+ " function test() {\n"
117-
+ " log(Intl.getCanonicalLocales('EN-us'));\n"
118-
+ " log(Intl.getCanonicalLocales(['en-US', 'fr-FR', 'ja-JP', 'EN-US']));\n"
119-
+ " log(Intl.getCanonicalLocales('zh-hant-tw'));\n"
120-
+ " log(Intl.getCanonicalLocales('en-latn-us'));\n"
121-
+ " log(Intl.getCanonicalLocales(new Intl.Locale('ja-JP')));\n"
122-
+ " log(Intl.getCanonicalLocales([new Intl.Locale('en-US'), new Intl.Locale('fr')]));\n"
123-
+ " log(Intl.getCanonicalLocales(new String('en-US')));\n"
124-
+ " log(Intl.getCanonicalLocales([new String('ja-JP')]));\n"
116+
+ " try { log(Intl.getCanonicalLocales('EN-us')); } catch(e) { logEx(e) }\n"
117+
+ " try { log(Intl.getCanonicalLocales(['en-US', 'fr-FR', 'ja-JP', 'EN-US'])); } catch(e) { logEx(e) }\n"
118+
+ " try { log(Intl.getCanonicalLocales('zh-hant-tw')); } catch(e) { logEx(e) }\n"
119+
+ " try { log(Intl.getCanonicalLocales('en-latn-us')); } catch(e) { logEx(e) }\n"
120+
+ " try { log(Intl.getCanonicalLocales(new Intl.Locale('ja-JP'))); } catch(e) { logEx(e) }\n"
121+
+ " try { log(Intl.getCanonicalLocales([new Intl.Locale('en-US'), new Intl.Locale('fr')])); } catch(e) { logEx(e) }\n"
122+
+ " try { log(Intl.getCanonicalLocales(String('en-US'))); } catch(e) { logEx(e) }\n"
123+
+ " try { log(Intl.getCanonicalLocales(new String('en-US'))); } catch(e) { logEx(e) }\n"
124+
+ " try { log(Intl.getCanonicalLocales([new String('ja-JP')])); } catch(e) { logEx(e) }\n"
125125
+ " try { log(Intl.getCanonicalLocales(null)); } catch(e) { logEx(e) }\n"
126126
+ " try { log(Intl.getCanonicalLocales(undefined)); } catch(e) { logEx(e) }\n"
127127
+ " try { log(Intl.getCanonicalLocales([])); } catch(e) { logEx(e) }\n"

0 commit comments

Comments
 (0)