1 module awebview.wrapper.jsobject;
2 
3 import std.range;
4 import std.utf;
5 
6 import awebview.wrapper.cpp;
7 import awebview.wrapper.jsarray : JSArray, JSArrayCpp;
8 import awebview.wrapper.jsvalue : JSValue;
9 import awebview.wrapper.webstring : WebString, WebStringCpp;
10 import awebview.wrapper.constants;
11 import awebview.wrapper.weakref;
12 import awebview.wrapper.cpp.mmanager;
13 
14 public import awebview.wrapper.cpp : JSObjectType;
15 
16 import carbon.nonametype;
17 
18 debug import std.stdio;
19 
20 struct JSObject
21 {
22     ~this() nothrow @nogc
23     {
24         if(this._field.instance_.local !is null)
25             JSObjectMember.dtor(this.cppObj!false);
26     }
27 
28 
29     this(this) nothrow @nogc
30     {
31         JSObject copy;
32         JSObjectMember.ctor(copy.cppObj!false, this.cppObj);
33         this._field = copy._field;
34         copy._field.instance_.local = null;
35     }
36 
37 
38     @property
39     CppObj cppObj(bool withInitialize = true)() nothrow @trusted @nogc
40     {
41         CppObj ret = cast(CppObj)cast(void*)&_field;
42 
43       static if(withInitialize)
44         if(_field.instance_.local is null)
45             JSObjectMember.ctor(ret);
46 
47         return ret;
48     }
49 
50 
51     @property
52     inout(CppObj) cppObj(this T)() inout nothrow @trusted @nogc
53     if(is(T == const) || is(T == immutable))
54     {
55         if(_field.instance_.local is null)
56             return cast(inout(CppObj))cast(inout(void)*)&JSObjectConsts._emptyInstance._field;
57         else
58             return cast(inout(CppObj))cast(inout(void)*)&_field;
59     }
60 
61 
62     @property
63     uint remoteId() const nothrow @nogc
64     {
65         return JSObjectMember.remote_id(this.cppObj);
66     }
67 
68 
69     @property
70     int refCount() const nothrow @nogc
71     {
72         return JSObjectMember.ref_count(this.cppObj);
73     }
74 
75 
76     @property
77     JSObjectType type() const nothrow @nogc
78     {
79         return JSObjectMember.type(this.cppObj);
80     }
81 
82 
83     @property
84     JSArray propertyNames() const nothrow @nogc
85     {
86         JSArray ja;
87         JSObjectMember.GetPropertyNames(this.cppObj, ja.cppObj);
88         return ja;
89     }
90 
91 
92     bool hasProperty(string str) const nothrow @nogc
93     {
94         WebString ws = str;
95         return hasProperty(ws);
96     }
97 
98 
99     bool hasProperty(in WebString str) const nothrow @nogc
100     {
101         return JSObjectMember.HasProperty(this.cppObj, str.cppObj);
102     }
103 
104 
105     JSValue getProperty(string str) const nothrow @nogc
106     {
107         WebString ws = str;
108         return getProperty(ws);
109     }
110 
111 
112     JSValue getProperty(in WebString str) const nothrow @nogc
113     {
114         JSValue jv;
115         JSObjectMember.GetProperty(this.cppObj, str.cppObj, jv.cppObj);
116         return jv;
117     }
118 
119 
120     void setProperty(in string str, in JSValue value) nothrow @nogc
121     {
122         WebString ws = str;
123         setProperty(ws, value);
124     }
125 
126 
127     void setProperty(in WebString str, in JSValue value) nothrow @nogc
128     {
129         JSObjectMember.SetProperty(this.cppObj, str.cppObj, value.cppObj);
130     }
131 
132 
133     void opIndexAssign(T)(T v, string str)
134     if(is(typeof(JSValue(v)) == JSValue))
135     {
136         setProperty(str, v);
137     }
138 
139 
140     JSValue opIndex(string str)
141     {
142         return getProperty(str);
143     }
144 
145 
146     void setPropertyAsync(in string str, in JSObject value) nothrow @nogc
147     {
148         WebString ws = str;
149         setPropertyAsync(ws, value);
150     }
151 
152 
153     void setPropertyAsync(in WebString str, in JSObject value) nothrow @nogc
154     {
155         JSObjectMember.SetPropertyAsync(this.cppObj, str.cppObj, value.cppObj);
156     }
157 
158 
159     void removeProperty(in string str) nothrow @nogc
160     {
161         WebString ws = str;
162         removeProperty(ws);
163     }
164 
165 
166     void removeProperty(in WebString str) nothrow @nogc
167     {
168         JSObjectMember.RemoveProperty(this.cppObj, str.cppObj);
169     }
170 
171 
172     @property
173     JSArray getMethodNames() const nothrow @nogc
174     {
175         JSArray ja;
176         JSObjectMember.GetMethodNames(this.cppObj, ja.cppObj);
177         return ja;
178     }
179 
180 
181     @property
182     bool hasMethod(Char)(in Char[] str) const nothrow @nogc
183     {
184         WebString ws = str;
185         return hasMethod(ws);
186     }
187 
188 
189     @property
190     bool hasMethod(in WebString str) const nothrow @nogc
191     {
192         return JSObjectMember.HasMethod(this.cppObj, str.cppObj);
193     }
194 
195 
196     JSValue invoke(in WebString str, in JSArray args) nothrow @nogc
197     {
198         JSValue jv;
199         JSObjectMember.Invoke(this.cppObj, str.cppObj, args.cppObj, jv.cppObj);
200         return jv;
201     }
202 
203 
204     void invokeAsync(in WebString str, in JSArray args) nothrow @nogc
205     {
206         JSObjectMember.InvokeAsync(this.cppObj, str.cppObj, args.cppObj);
207     }
208 
209 
210     void toString(scope void delegate(const(char)[]) sink) const
211     {
212         WebString str;
213         JSObjectMember.ToString(this.cppObj, str.cppObj);
214         foreach(char e; str.data.byChar)
215             put(sink, e);
216     }
217 
218 
219     void setCustomMethod(in WebString str, bool hasReturnValue) @nogc nothrow
220     {
221         JSObjectMember.SetCustomMethod(this.cppObj, str.cppObj, hasReturnValue);
222     }
223 
224 
225     void setCustomMethod(in string str, bool hasReturnValue) @nogc nothrow
226     {
227         WebString ws = str;
228         setCustomMethod(ws, hasReturnValue);
229     }
230 
231 
232     @property
233     awebview.wrapper.cpp.Awesomium.Error lastError() const nothrow @nogc
234     {
235         return JSObjectMember.last_error(this.cppObj);
236     }
237 
238 
239     static
240     auto weakRef(H)(H ws)
241     if(is(H : const(CppObj)))
242     {
243       static if(is(H == CppObj))
244         JSObject* wsp = cast(JSObject*)cast(void*)ws;
245       else static if(is(H == const(CppObj)))
246         const(JSObject)* wsp = cast(const(JSObject)*)cast(const(void)*)ws;
247       else
248         immutable(JSObject)* wsp = cast(immutable(JSObject)*)cast(immutable(void)*)ws;
249 
250         return refP(wsp);
251     }
252 
253   private:
254     alias CppObj = awebview.wrapper.cpp.JSObject;
255     CppObj.Field _field;
256 }
257 
258 
259 abstract class JSMethodHandler : awebview.wrapper.cpp.IJSMethodHandlerD
260 {
261     this()
262     {
263         auto id = MemoryManager.instance.register(cast(void*)this);
264         _cppObj = JSMethodHandlerD2CppMember.newCtor(this, id);
265     }
266 
267 
268     ~this()
269     {
270         JSMethodHandlerD2CppMember.deleteDtor(_cppObj);
271     }
272 
273 
274     @property
275     inout(CppObj) cppObj() inout pure nothrow @safe @nogc
276     {
277         return _cppObj;
278     }
279 
280 
281   extern(C++)
282   {
283     void call(awebview.wrapper.cpp.WebView view,
284               uint objId, const(awebview.wrapper.cpp.WebString) methodName,
285               const(awebview.wrapper.cpp.JSArray) args)
286     {
287         onCall(view, objId, methodName.weakRef!WebStringCpp, args.weakRef!JSArrayCpp);
288     }
289 
290 
291     void callWithReturnValue(
292         awebview.wrapper.cpp.WebView view,
293         uint objId, const(awebview.wrapper.cpp.WebString) methodName,
294         const(awebview.wrapper.cpp.JSArray) args,
295         awebview.wrapper.cpp.JSValue dst)
296     {
297         dst.weakRef!JSValue = onCallWithRV(view, objId, methodName.weakRef!WebStringCpp, args.weakRef!JSArrayCpp);
298     }
299   }
300 
301 
302     void onCall(awebview.wrapper.cpp.WebView view,
303                 uint objId, WeakRef!(const(WebStringCpp)) methodName,
304                 WeakRef!(const(JSArrayCpp)) args);
305 
306 
307     JSValue onCallWithRV(
308         awebview.wrapper.cpp.WebView view,
309         uint objId, WeakRef!(const(WebStringCpp)) methodName,
310         WeakRef!(const(JSArrayCpp)) args);
311 
312 
313   private:
314     CppObj _cppObj;
315 
316     alias CppObj = awebview.wrapper.cpp.JSMethodHandlerD2Cpp;
317 }