1 module javascriptcore.Context;
2 
3 private import glib.ConstructionException;
4 private import glib.Str;
5 private import gobject.ObjectG;
6 private import javascriptcore.Class;
7 private import javascriptcore.Exception;
8 private import javascriptcore.Value;
9 private import javascriptcore.VirtualMachine;
10 private import javascriptcore.c.functions;
11 public  import javascriptcore.c.types;
12 
13 
14 /**
15  * JSCContext represents a JavaScript execution context, where all operations
16  * take place and where the values will be associated.
17  * 
18  * When a new context is created, a global object is allocated and the built-in JavaScript
19  * objects (Object, Function, String, Array) are populated. You can execute JavaScript in
20  * the context by using jsc_context_evaluate() or jsc_context_evaluate_with_source_uri().
21  * It's also possible to register custom objects in the context with jsc_context_register_class().
22  */
23 public class Context : ObjectG
24 {
25 	/** the main Gtk struct */
26 	protected JSCContext* jSCContext;
27 
28 	/** Get the main Gtk struct */
29 	public JSCContext* getContextStruct(bool transferOwnership = false)
30 	{
31 		if (transferOwnership)
32 			ownedRef = false;
33 		return jSCContext;
34 	}
35 
36 	/** the main Gtk struct as a void* */
37 	protected override void* getStruct()
38 	{
39 		return cast(void*)jSCContext;
40 	}
41 
42 	/**
43 	 * Sets our main struct and passes it to the parent class.
44 	 */
45 	public this (JSCContext* jSCContext, bool ownedRef = false)
46 	{
47 		this.jSCContext = jSCContext;
48 		super(cast(GObject*)jSCContext, ownedRef);
49 	}
50 
51 
52 	/** */
53 	public static GType getType()
54 	{
55 		return jsc_context_get_type();
56 	}
57 
58 	/**
59 	 * Create a new #JSCContext. The context is created in a new #JSCVirtualMachine.
60 	 * Use jsc_context_new_with_virtual_machine() to create a new #JSCContext in an
61 	 * existing #JSCVirtualMachine.
62 	 *
63 	 * Returns: the newly created #JSCContext.
64 	 *
65 	 * Throws: ConstructionException GTK+ fails to create the object.
66 	 */
67 	public this()
68 	{
69 		auto __p = jsc_context_new();
70 
71 		if(__p is null)
72 		{
73 			throw new ConstructionException("null returned by new");
74 		}
75 
76 		this(cast(JSCContext*) __p, true);
77 	}
78 
79 	/**
80 	 * Create a new #JSCContext in @virtual_machine.
81 	 *
82 	 * Params:
83 	 *     vm = a #JSCVirtualMachine
84 	 *
85 	 * Returns: the newly created #JSCContext.
86 	 *
87 	 * Throws: ConstructionException GTK+ fails to create the object.
88 	 */
89 	public this(VirtualMachine vm)
90 	{
91 		auto __p = jsc_context_new_with_virtual_machine((vm is null) ? null : vm.getVirtualMachineStruct());
92 
93 		if(__p is null)
94 		{
95 			throw new ConstructionException("null returned by new_with_virtual_machine");
96 		}
97 
98 		this(cast(JSCContext*) __p, true);
99 	}
100 
101 	/**
102 	 * Get the #JSCContext that is currently executing a function. This should only be
103 	 * called within a function or method callback, otherwise %NULL will be returned.
104 	 *
105 	 * Returns: the #JSCContext that is currently executing.
106 	 */
107 	public static Context getCurrent()
108 	{
109 		auto __p = jsc_context_get_current();
110 
111 		if(__p is null)
112 		{
113 			return null;
114 		}
115 
116 		return ObjectG.getDObject!(Context)(cast(JSCContext*) __p);
117 	}
118 
119 	/**
120 	 * Check the given @code in @context for syntax errors. The @line_number is the starting line number in @uri;
121 	 * the value is one-based so the first line is 1. @uri and @line_number are only used to fill the @exception.
122 	 * In case of errors @exception will be set to a new #JSCException with the details. You can pass %NULL to
123 	 * @exception to ignore the error details.
124 	 *
125 	 * Params:
126 	 *     code = a JavaScript script to check
127 	 *     length = length of @code, or -1 if @code is a nul-terminated string
128 	 *     mode = a #JSCCheckSyntaxMode
129 	 *     uri = the source URI
130 	 *     lineNumber = the starting line number
131 	 *     exception = return location for a #JSCException, or %NULL to ignore
132 	 *
133 	 * Returns: a #JSCCheckSyntaxResult
134 	 */
135 	public JSCCheckSyntaxResult checkSyntax(string code, ptrdiff_t length, JSCCheckSyntaxMode mode, string uri, uint lineNumber, out JException exception)
136 	{
137 		JSCException* outexception = null;
138 
139 		auto __p = jsc_context_check_syntax(jSCContext, Str.toStringz(code), length, mode, Str.toStringz(uri), lineNumber, &outexception);
140 
141 		exception = ObjectG.getDObject!(JException)(outexception);
142 
143 		return __p;
144 	}
145 
146 	/**
147 	 * Clear the uncaught exception in @context if any.
148 	 */
149 	public void clearException()
150 	{
151 		jsc_context_clear_exception(jSCContext);
152 	}
153 
154 	/**
155 	 * Evaluate @code in @context.
156 	 *
157 	 * Params:
158 	 *     code = a JavaScript script to evaluate
159 	 *     length = length of @code, or -1 if @code is a nul-terminated string
160 	 *
161 	 * Returns: a #JSCValue representing the last value generated by the script.
162 	 */
163 	public Value evaluate(string code, ptrdiff_t length)
164 	{
165 		auto __p = jsc_context_evaluate(jSCContext, Str.toStringz(code), length);
166 
167 		if(__p is null)
168 		{
169 			return null;
170 		}
171 
172 		return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true);
173 	}
174 
175 	/**
176 	 * Evaluate @code and create an new object where symbols defined in @code will be added as properties,
177 	 * instead of being added to @context global object. The new object is returned as @object parameter.
178 	 * Similar to how jsc_value_new_object() works, if @object_instance is not %NULL @object_class must be provided too.
179 	 * The @line_number is the starting line number in @uri; the value is one-based so the first line is 1.
180 	 * @uri and @line_number will be shown in exceptions and they don't affect the behavior of the script.
181 	 *
182 	 * Params:
183 	 *     code = a JavaScript script to evaluate
184 	 *     length = length of @code, or -1 if @code is a nul-terminated string
185 	 *     objectInstance = an object instance
186 	 *     objectClass = a #JSCClass or %NULL to use the default
187 	 *     uri = the source URI
188 	 *     lineNumber = the starting line number
189 	 *     object = return location for a #JSCValue.
190 	 *
191 	 * Returns: a #JSCValue representing the last value generated by the script.
192 	 */
193 	public Value evaluateInObject(string code, ptrdiff_t length, void* objectInstance, Class objectClass, string uri, uint lineNumber, out Value object)
194 	{
195 		JSCValue* outobject = null;
196 
197 		auto __p = jsc_context_evaluate_in_object(jSCContext, Str.toStringz(code), length, objectInstance, (objectClass is null) ? null : objectClass.getClassStruct(), Str.toStringz(uri), lineNumber, &outobject);
198 
199 		object = ObjectG.getDObject!(Value)(outobject);
200 
201 		if(__p is null)
202 		{
203 			return null;
204 		}
205 
206 		return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true);
207 	}
208 
209 	/**
210 	 * Evaluate @code in @context using @uri as the source URI. The @line_number is the starting line number
211 	 * in @uri; the value is one-based so the first line is 1. @uri and @line_number will be shown in exceptions and
212 	 * they don't affect the behavior of the script.
213 	 *
214 	 * Params:
215 	 *     code = a JavaScript script to evaluate
216 	 *     length = length of @code, or -1 if @code is a nul-terminated string
217 	 *     uri = the source URI
218 	 *     lineNumber = the starting line number
219 	 *
220 	 * Returns: a #JSCValue representing the last value generated by the script.
221 	 */
222 	public Value evaluateWithSourceUri(string code, ptrdiff_t length, string uri, uint lineNumber)
223 	{
224 		auto __p = jsc_context_evaluate_with_source_uri(jSCContext, Str.toStringz(code), length, Str.toStringz(uri), lineNumber);
225 
226 		if(__p is null)
227 		{
228 			return null;
229 		}
230 
231 		return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true);
232 	}
233 
234 	/**
235 	 * Get the last unhandled exception thrown in @context by API functions calls.
236 	 *
237 	 * Returns: a #JSCException or %NULL if there isn't any
238 	 *     unhandled exception in the #JSCContext.
239 	 */
240 	public JException getException()
241 	{
242 		auto __p = jsc_context_get_exception(jSCContext);
243 
244 		if(__p is null)
245 		{
246 			return null;
247 		}
248 
249 		return ObjectG.getDObject!(JException)(cast(JSCException*) __p);
250 	}
251 
252 	/**
253 	 * Get a #JSCValue referencing the @context global object
254 	 *
255 	 * Returns: a #JSCValue
256 	 */
257 	public Value getGlobalObject()
258 	{
259 		auto __p = jsc_context_get_global_object(jSCContext);
260 
261 		if(__p is null)
262 		{
263 			return null;
264 		}
265 
266 		return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true);
267 	}
268 
269 	/**
270 	 * Get a property of @context global object with @name.
271 	 *
272 	 * Params:
273 	 *     name = the value name
274 	 *
275 	 * Returns: a #JSCValue
276 	 */
277 	public Value getValue(string name)
278 	{
279 		auto __p = jsc_context_get_value(jSCContext, Str.toStringz(name));
280 
281 		if(__p is null)
282 		{
283 			return null;
284 		}
285 
286 		return ObjectG.getDObject!(Value)(cast(JSCValue*) __p, true);
287 	}
288 
289 	/**
290 	 * Get the #JSCVirtualMachine where @context was created.
291 	 *
292 	 * Returns: the #JSCVirtualMachine where the #JSCContext was created.
293 	 */
294 	public VirtualMachine getVirtualMachine()
295 	{
296 		auto __p = jsc_context_get_virtual_machine(jSCContext);
297 
298 		if(__p is null)
299 		{
300 			return null;
301 		}
302 
303 		return ObjectG.getDObject!(VirtualMachine)(cast(JSCVirtualMachine*) __p);
304 	}
305 
306 	/**
307 	 * Remove the last #JSCExceptionHandler previously pushed to @context with
308 	 * jsc_context_push_exception_handler().
309 	 */
310 	public void popExceptionHandler()
311 	{
312 		jsc_context_pop_exception_handler(jSCContext);
313 	}
314 
315 	/**
316 	 * Push an exception handler in @context. Whenever a JavaScript exception happens in
317 	 * the #JSCContext, the given @handler will be called. The default #JSCExceptionHandler
318 	 * simply calls jsc_context_throw_exception() to throw the exception to the #JSCContext.
319 	 * If you don't want to catch the exception, but only get notified about it, call
320 	 * jsc_context_throw_exception() in @handler like the default one does.
321 	 * The last exception handler pushed is the only one used by the #JSCContext, use
322 	 * jsc_context_pop_exception_handler() to remove it and set the previous one. When @handler
323 	 * is removed from the context, @destroy_notify i called with @user_data as parameter.
324 	 *
325 	 * Params:
326 	 *     handler = a #JSCExceptionHandler
327 	 *     userData = user data to pass to @handler
328 	 *     destroyNotify = destroy notifier for @user_data
329 	 */
330 	public void pushExceptionHandler(JSCExceptionHandler handler, void* userData, GDestroyNotify destroyNotify)
331 	{
332 		jsc_context_push_exception_handler(jSCContext, handler, userData, destroyNotify);
333 	}
334 
335 	/**
336 	 * Register a custom class in @context using the given @name. If the new class inherits from
337 	 * another #JSCClass, the parent should be passed as @parent_class, otherwise %NULL should be
338 	 * used. The optional @vtable parameter allows to provide a custom implementation for handling
339 	 * the class, for example, to handle external properties not added to the prototype.
340 	 * When an instance of the #JSCClass is cleared in the context, @destroy_notify is called with
341 	 * the instance as parameter.
342 	 *
343 	 * Params:
344 	 *     name = the class name
345 	 *     parentClass = a #JSCClass or %NULL
346 	 *     vtable = an optional #JSCClassVTable or %NULL
347 	 *     destroyNotify = a destroy notifier for class instances
348 	 *
349 	 * Returns: a #JSCClass
350 	 */
351 	public Class registerClass(string name, Class parentClass, JSCClassVTable* vtable, GDestroyNotify destroyNotify)
352 	{
353 		auto __p = jsc_context_register_class(jSCContext, Str.toStringz(name), (parentClass is null) ? null : parentClass.getClassStruct(), vtable, destroyNotify);
354 
355 		if(__p is null)
356 		{
357 			return null;
358 		}
359 
360 		return ObjectG.getDObject!(Class)(cast(JSCClass*) __p);
361 	}
362 
363 	/**
364 	 * Set a property of @context global object with @name and @value.
365 	 *
366 	 * Params:
367 	 *     name = the value name
368 	 *     value = a #JSCValue
369 	 */
370 	public void setValue(string name, Value value)
371 	{
372 		jsc_context_set_value(jSCContext, Str.toStringz(name), (value is null) ? null : value.getValueStruct());
373 	}
374 
375 	/**
376 	 * Throw an exception to @context using the given error message. The created #JSCException
377 	 * can be retrieved with jsc_context_get_exception().
378 	 *
379 	 * Params:
380 	 *     errorMessage = an error message
381 	 */
382 	public void throwMessage(string errorMessage)
383 	{
384 		jsc_context_throw(jSCContext, Str.toStringz(errorMessage));
385 	}
386 
387 	/**
388 	 * Throw @exception to @context.
389 	 *
390 	 * Params:
391 	 *     exception = a #JSCException
392 	 */
393 	public void throwException(JException exception)
394 	{
395 		jsc_context_throw_exception(jSCContext, (exception is null) ? null : exception.getExceptionStruct());
396 	}
397 
398 	/**
399 	 * Throw an exception to @context using the given error name and message. The created #JSCException
400 	 * can be retrieved with jsc_context_get_exception().
401 	 *
402 	 * Params:
403 	 *     errorName = the error name
404 	 *     errorMessage = an error message
405 	 */
406 	public void throwWithName(string errorName, string errorMessage)
407 	{
408 		jsc_context_throw_with_name(jSCContext, Str.toStringz(errorName), Str.toStringz(errorMessage));
409 	}
410 }