I'm using WebKitGTK in Lua (via lgi) and I want to set up some kind of
communication channel between JS and Lua, that can be used to pass
data back and forth between them and load resources.

The best approach to me looks like using AJAX (via jQuery) to place
requests to a custom protocol, and handling those requests on the Lua
side. I can catch those requests in Lua in the
resource-request-starting signal, but I can't seem to push a response
- regardless of what I do in the handler, it only triggers the AJAX
error handler, with a response code of 0 and empty error string.

The Lua code is:
------------------------------8<------------------------------
#!/usr/bin/env lua5.1
package.path = './src/?.lua;' .. package.path
package.cpath = './src/?/build/?.so;' .. package.cpath
lgi = require('lgi')
gtk = lgi.require('Gtk', '3.0')
gdk = lgi.require('Gdk', '3.0')
gio = lgi.require('Gio', '2.0')
webkit = lgi.require('WebKit', '3.0') --requires libwebkitgtk-3.0-dev
glib = lgi.GLib
gobject = lgi.GObject
pango = lgi.Pango
cairo = lgi.cairo --lowercase for some reason
soup = lgi.Soup


--create the main window and webview
webkit.set_cache_model(webkit.CacheModel.DOCUMENT_VIEWER)
local webview = webkit.WebView.new()
local window = gtk.Window {
        title = "Web View",
        resizable = true,
        type = gtk.WindowType.TOPLEVEL,
        type_hint = gdk.WindowTypeHint.NORMAL,
        default_width = 200,
        default_height = 200,
        decorated = true,
        resizable = true,
        gtk.ScrolledWindow { expand = true, webview },
        on_destroy = function() os.exit(0) end,
}

--configure the webview
local settings = webkit.WebSettings.new()
settings.enable_accelerated_compositing = true
settings.enable_webaudio = true --enable some experimental JS APIs
settings.enable_webgl = true

--required to allow scripts in file:///* to access http://* and our custom
--protocols used for JS/Lua communication
settings.enable_universal_access_from_file_uris = true
webview:set_settings(settings)


--log JS console messages
--the default handler logs them too, but it's ugly.
webview.on_console_message = function(webview, message, line, source)
        print(('<JS> %s:%d: %s'):format(source, line, message))
        return true
end

webview.on_load_error = function(webview, frame, uri, err)
        io.stderr:write(("Load error: %s: %s\n"):format(uri, err.message))
end

webview.on_resource_load_failed = function(webview, frame, resource, err)
        local uri = resource:get_uri()
        io.stderr:write(("Resource load failed: %s: %s\n"):format(uri, 
err.message))
end


--set up URI request handler
webview.on_resource_request_starting =
        function(webview, frame, resource, request, response)
                print("Request", request:get_uri())
                --http://developer.gnome.org/libsoup/stable/SoupMessage.html
                local msg = request:get_message()
                msg.response_headers:append('Access-Control-Allow-Origin', '*')

                if request:get_uri():sub(1, 6) == 'lol://' then
                        --this doesn't seem to work; the message is never 
received by the
                        --client and it fails with error code 0
                        local str = "bananas"
                        request:set_uri('data:text/plain;charset=UTF-8,lol')
                        msg:set_status(200)
                        msg:set_response("text/plain", soup.MemoryUse.COPY, 
str, #str)

                        --returning true or false here makes no difference
                end
        end


--load main page
webview:load_uri('file://' .. os.getenv('PWD') .. '/data/main.html')


--blastoff
window:show_all()
local ok, err = xpcall(gtk.main, debug.traceback)
if not ok then
        io.stderr:write(tostring(err) .. '\n')
        os.exit(1)
end
------------------------------8<------------------------------


The Javascript code is:

------------------------------8<------------------------------
var n = 0
$(document).ready(function() {
        console.log("Loaded")
        $('#hello').text('!')

        $.ajax({
                url: "lol://wtf?hax=yup",
                isLocal: true, //makes no difference
                success: function(data, status, jqXHR) {
                        console.log("AJAX recv:" + data)
                },
                error: function(jqXHR, status, err) {
                        console.log("AJAX error: " + status + "; " + err +
                                "; resp=" + jqXHR.status)
                }
        })

        setInterval(function() {
                $('#hello').text(n)
                n = n + 1
        }, 1000)
})
------------------------------8<------------------------------

It logs an error: "AJAX error: error; ; resp=0" - i.e. status =
"error", err = "", jqXHR.status = 0. Is there more I need to do in my
handler to return a data string and have it consider the request
successful?


-- 
Sent from my Game Boy.
_______________________________________________
webkit-gtk mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-gtk

Reply via email to