Interacting with JavaScript

Initialising the Lua global namespace

You can initialise the Lua global namespace with functions and values for your application. Simply add JavaScript keys and values to window.starlight.config.env before including the Starlight script.

The JavaScript functions can be called directly from within the Lua environment.

⋮
<script type="application/lua">
  print('API version:', API_VERSION)
  print('Time:', getTimestamp())
</script>
 
<script>
  window.starlight = {
    config: {
      env: {
        _API_VERSION: 2,
        getTimestamp: function () {
          return Date.now();
        },
      },
    },
  };
</script>
⋮

API version: 2
Time:  1471725254319

Run in JS Bin

See also: Creating Lua tables in JavaScript

Accessing the JavaScript world from Lua

The JavaScript window object is available in the Lua global namespace with the same name, but be aware window ~= _G. You need to access all JavaScript APIs and the DOM through the window table, for example:

⋮
<button id="click-me">Click me</button>
 
<script type="application/lua">
  local button = window.document:getElementById('click-me')
 
  button:addEventListener('click', function () 
    window:alert('Hello!')
  end)
</script>
⋮
Run in JS Bin

window.extract()

If you really want to access the properties of window in the global namespace, you can call window.extract(). Make sure you always use the colon syntax to call methods on the DOM, as in the examples above.

⋮
<button id="hello">Click me</button>
 
<script type="application/lua">
  window.extract()
  local button = document:getElementById('hello')
 
  button:addEventListener('click', function () 
    local p = document:createElement('p')
    p.textContent = 'Hello!!'
    document.body:appendChild(p)
  end)
</script>
⋮
Run in JS Bin

Creating Lua tables in JavaScript

Lua tables can be created in JavaScript and then be passed back into the Lua world.

When accessing properties of a Lua table object in JavaScript, you should use the get() and set() methods. rawget() and rawset() are also available to bypass metamethods.

⋮
<script type="application/lua">
  local pos = getPosition();
  print('Latitude:', pos.lat)
  print('Longitude:', pos.lng)
</script>
 
<script>
  window.starlight = {
    config: {
      env: {
        getPosition: function () {
          var pos = new starlight.runtime.T();
          pos.set('lat', 51.74257);
          pos.set('lng', -0.30186);
          return pos;
        }
      }
    }
  };
</script>
⋮

Latitude:  51.74257
Longitude: -0.30186

Run in JS Bin

You can also pass a JavaScript object or array to the table constructor and the resulting table will be prepopulated with the correct values.

⋮
<script type="application/lua">
  local pos = getPosition();
  print('Latitude:', pos.lat)
  print('Longitude:', pos.lng)
</script>
 
<script>
  window.starlight = {
    config: {
      env: {
        getPosition: function () {
          return new starlight.runtime.T({
            lat: 51.74257,
            lng: -0.30186,
          });
        }
      }
    }
  };
</script>
⋮

Latitude:  51.74257
Longitude: -0.30186

Run in JS Bin

Calling Lua standard library functions

The Lua global namespace is accessible via starlight.runtime._G. This can be used to access and execute standard library functions.

Remember that _G is a Lua table and therefore we need to use _G.get() to access properties.

⋮
<script type="application/lua">
  local proxy = getProxy();
  local x = proxy.starlight
  proxy.rules = 'ok'
</script>
 
<script>
  window.starlight = {
    config: {
      env: {
        getProxy: function () {
          var t = new starlight.runtime.T();
          var mt = new starlight.runtime.T({
            __index: function (table, key) {
              console.log('GET', key);
            },
            __newindex: function (table, key, value) {
              console.log('SET', key, value)
            }
          });
            starlight.runtime._G.get('setmetatable')(t, mt);
          return t; 
  }   }   } }; </script> ⋮

GET   starlight
SET   rules    ok

Run in JS Bin

Returning multiple values from JavaScript

Simply return a JavaScript array containing the values.

Remember that, if you wish to return a Lua array, you should return a Lua table. See Creating Lua tables in JavaScript

⋮
<script type="application/lua">
  local lat, lng = getLatLng();
  print('Latitude:', lat)
  print('Longitude:', lng)
</script>
 
<script>
  window.starlight = {
    config: {
      env: {
        getLatLng: function () {
          return [51.74257, -0.30186];
        }
      }
    }
  };
</script>
⋮

Latitude:  51.74257
Longitude: -0.30186

Run in JS Bin

Throwing Lua errors from JavaScript

When you expose your JavaScript API to the Lua world, you can also validate and throw Lua errors.

⋮
<button>DO NOT CLICK!</button>
 
<script>
  var button = document.querySelector('button');
  button.addEventListener('click', function () {
    throw new starlight.runtime.LuaError('Boooom!');
  });
</script> 

Uncaught LuaError: Boooom!

Run in JS Bin