Introduction To XojoScript

XojoScript allows your apps to run Xojo source code within itself. This feature is a great way to make your app scriptable for your power users. Scripts take full advantage of the Xojo language and provide limited access to the framework. The Scripting Language section has full details on what is supported. You can also provide your own functionality that is accessibly from scripts.

You run scripts using the XojoScript class, which provides ways for you to assign source code, run it, supply input, get output, handle errors, interface with your application and more.

Running code

To get started, you need an instance of the XojoScript class. You can drag a XojoScript control to a Window, WebPage or Container. Or you can create an instance in your code.

The next thing to do is assign a script to it. This is done by assigning the source code (as a string) to the Source property. In this example, Script is the name of a XojoScript object that has been added to a window:

Script.Source = "Print ""Hello, World! """

The Print command outputs the supplied text to the Print event of the XojoScript instance.

Note: You can access the Print event by subclassing XojoScript, by dragging a XojoScript control onto your layout or by using AddHandler.

This code in the Print event displays a message with the supplied text:

MessageBox(msg)

Lastly, you can run the script by calling the Run method:

Script.Source = "Print ""Hello, World!"""
Script.Run

Handling errors

Since XojoScript contains source code, it is possible that there could be errors in the source code. These events are used to handle XojoScript code errors: CompileError and RuntimeError. In addition, the CompilerWarning event can tell you about warnings in the XojoScript code.

CompilerError

The CompilerError event is called if there is a problem compiling the script because of invalid syntax or some other problem. This event provides you with the location of the error (using the XojoScriptLocation class), the error (as a XojoScript.Errors enum and extra errorInfo as a Dictionary). It is important to handle this event if you are allowing the user to supply scripts.

CompilerWarning

The CompilerWarning event handler is called when there is a warning compiling the script. This could indicate unused local variables, deprecations and other warnings. This event provides you with the location of the warning (using the XojoScriptLocation class), the warning (as a Warnings enum and extra warningInfo as a Dictionary). It is important to handle this event if you are allowing the user to supply scripts.

RuntimeError

The RuntimeError event is called if a runtime exception occurs while the script is running. The event provides the error as a RunTimeException which you can use to determine the type of exception that occurred. It is important to handle this event if you are allowing the user to supply their own scripts.

This code can display the run time exception that occurred:

Var dialog As New MessageDialog
dialog.Title = "Unhandled Exception"
dialog.Message = "Unhandled Exception"
dialog.Explanation = "A " + Introspection.GetType(error).Name + " was not caught."
If Not error.Message.IsEmpty Then
  dialog.Explanation = dialog.Explanation + " " + error.Message
End If

Call dialog.ShowModalWithin(Self)

XojoScriptLocation

This class has properties to provide you with information about an error or warning. You can use this information to let the user know where the problem is and even to highlight the text in the script.

These are the properties:

Property

Description

Character

The starting character of the part of the script with an error or warning. Use in conjunction with EndCharacter to highlight the text in the script.

Column

The starting column of the script error or warning.

EndCharacter

The ending character of the part of the script with an error or warning.

EndColumn

The ending column of the script error or warning.

EndLine

The ending line number of the script error or warning.

Line

The starting line number of the script error or warning.

Enumerations

Use the XojoScript.Errors and the XojoScript.Warnings enumerations to check for specific errors or warnings.

Interfacing with your app

Scripts run in a sandbox, which means they cannot directly interact with any of your app code beyond the specified events. This can often be too restrictive, so you have the option of making some of your app code available by using the Context property.

The Context is an object that you have instantiated. Your script is allowed to call the methods on this object as if they were global methods defined in the script. You can also have properties on the object that are available as if they were global properties defined in the script. The typical way to use this feature is to have a special class that knows how to interface with your app. For example, this class could have a Save method that calls the appropriate code in your application to save something. Because of the sandbox, XojoScript cannot access the class with the Save method, but by using the Context object as a go-between, you can make the Save method available to the script.

You assign the context like this:

Var controller As New MyAppController
Var script As New XojoScript
script.Context = controller

Then in the script, you can call the Save method as if it where any global method:

Var controller As New MyAppController
Var script As New XojoScript
script.Context = controller
script.Source = "Save"
script.Run

Advanced features

You can optimize code before running it by calling the Precompile method and supplying it a value from the XojoScript.OptimizationLevels enum: High, Low, None. Using higher optimization levels makes the script run faster, but it will take the script longer to compile. Unless your scripts are especially math intensive, there is little need to change the optimization level.

If Precompile returns True, then you can run the script using the Run method.

You can check the state of a script by comparing the State property to the States enumeration with values: Aborted, Complete, Ready, Running.