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