1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript;
16
17 import java.lang.reflect.Member;
18 import java.util.Arrays;
19 import java.util.LinkedHashSet;
20 import java.util.List;
21 import java.util.Set;
22
23 import org.htmlunit.BrowserVersion;
24 import org.htmlunit.corejs.javascript.FunctionObject;
25 import org.htmlunit.corejs.javascript.Scriptable;
26 import org.htmlunit.corejs.javascript.ScriptableObject;
27 import org.htmlunit.javascript.configuration.ClassConfiguration;
28 import org.htmlunit.javascript.configuration.ClassConfiguration.ConstantInfo;
29 import org.htmlunit.javascript.configuration.JavaScriptConfiguration;
30
31
32
33
34
35
36
37 public class RecursiveFunctionObject extends FunctionObject {
38
39 private final BrowserVersion browserVersion_;
40
41
42
43
44
45
46
47
48 public RecursiveFunctionObject(final String name, final Member methodOrConstructor,
49 final Scriptable scope, final BrowserVersion browserVersion) {
50 super(name, methodOrConstructor, scope);
51 browserVersion_ = browserVersion;
52 }
53
54
55
56
57 @Override
58 public boolean has(final String name, final Scriptable start) {
59 if (super.has(name, start)) {
60 return true;
61 }
62 for (Class<?> c = getMethodOrConstructor().getDeclaringClass().getSuperclass();
63 c != null; c = c.getSuperclass()) {
64 final Object scripatble = getParentScope().get(c.getSimpleName(), this);
65 if (scripatble instanceof Scriptable && ((Scriptable) scripatble).has(name, start)) {
66 return true;
67 }
68 }
69 return false;
70 }
71
72
73
74
75 @Override
76 public Object[] getIds() {
77 final Set<Object> objects = new LinkedHashSet<>();
78 objects.addAll(Arrays.asList(super.getIds()));
79
80 for (Class<?> c = getMethodOrConstructor().getDeclaringClass().getSuperclass();
81 c != null; c = c.getSuperclass()) {
82 final Object scripatble = getParentScope().get(c.getSimpleName(), this);
83 if (scripatble instanceof Scriptable) {
84 objects.addAll(Arrays.asList(((Scriptable) scripatble).getIds()));
85 }
86 }
87 return objects.toArray(new Object[0]);
88 }
89
90
91
92
93 @Override
94 public Object get(final String name, final Scriptable start) {
95 Object value = super.get(name, start);
96 if (value != NOT_FOUND) {
97 return value;
98 }
99
100 Class<?> klass = getPrototypeProperty().getClass();
101
102 while (value == NOT_FOUND && HtmlUnitScriptable.class.isAssignableFrom(klass)) {
103 final ClassConfiguration config = JavaScriptConfiguration.getInstance(browserVersion_)
104 .getClassConfiguration(klass.getSimpleName());
105 if (config != null) {
106 final List<ConstantInfo> constants = config.getConstants();
107 if (constants != null) {
108 for (final ConstantInfo constantInfo : constants) {
109 if (constantInfo.getName().equals(name)) {
110 value = ScriptableObject.getProperty((Scriptable) getPrototypeProperty(), name);
111 break;
112 }
113 }
114 }
115 }
116 klass = klass.getSuperclass();
117 }
118 return value;
119 }
120
121
122
123
124 @Override
125 public Scriptable getClassPrototype() {
126 return super.getClassPrototype();
127 }
128 }