Code Monkey home page Code Monkey logo

lorca's Introduction

Lorca

Build Status GoDoc Go Report Card

Lorca

A very small library to build modern HTML5 desktop apps in Go. It uses Chrome browser as a UI layer. Unlike Electron it doesn't bundle Chrome into the app package, but rather reuses the one that is already installed. Lorca establishes a connection to the browser window and allows calling Go code from the UI and manipulating UI from Go in a seamless manner.


Features

  • Pure Go library (no cgo) with a very simple API
  • Small application size (normally 5-10MB)
  • Best of both worlds - the whole power of HTML/CSS to make your UI look good, combined with Go performance and ease of development
  • Expose Go functions/methods and call them from JavaScript
  • Call arbitrary JavaScript code from Go
  • Asynchronous flow between UI and main app in both languages (async/await and Goroutines)
  • Supports loading web UI from the local web server or via data URL
  • Supports testing your app with the UI in the headless mode
  • Supports multiple app windows
  • Supports packaging and branding (e.g. custom app icons). Packaging for all three OS can be done on a single machine using GOOS and GOARCH variables.

Also, limitations by design:

  • Requires Chrome/Chromium >= 70 to be installed.
  • No control over the Chrome window yet (e.g. you can't remove border, make it transparent, control position or size).
  • No window menu (tray menus and native OS dialogs are still possible via 3rd-party libraries)

If you want to have more control of the browser window - consider using webview library with a similar API, so migration would be smooth.

Example

ui, _ := lorca.New("", "", 480, 320)
defer ui.Close()

// Bind Go function to be available in JS. Go function may be long-running and
// blocking - in JS it's represented with a Promise.
ui.Bind("add", func(a, b int) int { return a + b })

// Call JS function from Go. Functions may be asynchronous, i.e. return promises
n := ui.Eval(`Math.random()`).Float()
fmt.Println(n)

// Call JS that calls Go and so on and so on...
m := ui.Eval(`add(2, 3)`).Int()
fmt.Println(m)

// Wait for the browser window to be closed
<-ui.Done()

Also, see examples for more details about binding functions and packaging binaries.

Hello World

Here are the steps to run the hello world example.

cd examples/counter
go get
go run ./

How it works

Under the hood Lorca uses Chrome DevTools Protocol to instrument on a Chrome instance. First Lorca tries to locate your installed Chrome, starts a remote debugging instance binding to an ephemeral port and reads from stderr for the actual WebSocket endpoint. Then Lorca opens a new client connection to the WebSocket server, and instruments Chrome by sending JSON messages of Chrome DevTools Protocol methods via WebSocket. JavaScript functions are evaluated in Chrome, while Go functions actually run in Go runtime and returned values are sent to Chrome.

What's in a name?

There is kind of a legend, that before his execution Garcia Lorca have seen a sunrise over the heads of the soldiers and he said "And yet, the sun rises...". Probably it was the beginning of a poem. (J. Brodsky)

Lorca is an anagram of Carlo, a project with a similar goal for Node.js.

License

Code is distributed under MIT license, feel free to use it in your proprietary projects as well.

lorca's People

Contributors

1l0 avatar aligator avatar chenilim avatar erizocosmico avatar irobayna avatar jkuri avatar jsfaint avatar justinmichaelvieira avatar krzysztof-gzocha avatar kunalpowar avatar larrybattle avatar larrylutw avatar nrwiersma avatar oneo-me avatar rikiyafujii avatar robindiddams avatar seanburlington avatar slavakrampetz avatar srinivasa314 avatar szzhiyang avatar velut avatar yaodingyd avatar zncoder avatar zserge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lorca's Issues

Possible to make the UI have less Chrome functionality, particularly on right click?

I'm trying out lorca and I am new to Go. I have created a little web server and have got it showing in a UI with lorca (on win 10 if that matters). I have noticed that the UI window is still basically Chrome, but without the menus and tab bars. For example;

  • I can right click on the background, and the menu is the same as in Chrome, with commands like "Cast" and "Translate to English", Back/Forward, etc.
  • I can select and copy text.
  • If I hover over a hyperlink, the tooltip appears in the bottom of the window with the new address.
  • If I right click on a hyperlink, I can do things like "Open in Tab", which starts up a full version of Chrome.
  • If I right click on the programs titlebar, I get options like Print, Zoom, Back/Forward, "Open Browser Window", etc.

Can any of this be disabled by lorca, or is limiting the functionality only possible via the tools of HTML/CSS/JS? I don't think that CSS/JS will resolve the right click on the titlebar problems at all.

How does Electron handle this? (I've not developed with it)

Images from HTML UI stored locally, 1) how to be recognized by lorca and 2) be exported into the final .exe too?

Hey,

I've been playing around with lorca and I love it. I've decided to step up my go UI game and get Adobe XD. I just designed a really sleek looking UI, but there's one issue: I used local images. Transferring the html code to go was really smooth, as always, but when I loaded up the program, no local images appeared. I tried dragging the images into the local directory of the program, no luck. I wish to have a folder titled "assets" where I have all my png images. I have two questions:

  1. How do I get these photos to be recognized by lorca?
  2. When I'm all done with the program, how do I export the images with the exe so users don't have to lug around an assets folder?

Thank you, I'm loving lorca!

Invalid control character in URL

Using Windows 10, VSCode 1.31.1, ms-vscode.go 0.9.2, Chrome 72.0.3626.121

Running any of the examples results in:

API server listening at: 127.0.0.1:33546 2019/03/06 01:52:50 parse ws://127.0.0.1:53506/devtools/browser/a96b3406-d882-4162-bf59-b877b771845f : net/url: invalid control character in URL

is it the 'run' rises, or the 'sun' ?

I looked for references in Google for both words, but couldn't find any. Is it actually "And yet, the run rises..." or is there a typo and the correct quote is "And yet, the sun rises...". Sun seems to make more sense in context.

Lorca + Nuxt?

I have been working with your webview version and dabbling with react and vuejs. I really like the idea of lorca, as it even further simplifies the moving parts (no cgo). Do you know if there are any show stoppers in getting Lorca and Nuxt to play well?

If you think it is doable, do you have (or could you knock out) a "Hello World" showing how they would interact?

Update: By Nuxt, I am specifically using VueJS + Vuetify. Not that it would matter perhaps, but just in case...

Make lorca.Embed generate assets Go file for packages other than "main"

The current lorca.Embed() implementation contains the following:

fmt.Fprintf(w, `// Code generated by Lorca. DO NOT EDIT.
package %s
//...
, "main")

This prevents the function to generate code inside differently named packages. As it is, the function should take a third parameter package string, so that it can call Fprintf like this:

fmt.Fprintf(w, `// Code generated by Lorca. DO NOT EDIT.
package %s
//...
, pkg)

Something along the lines of

func Embed(pkg string, file string, dirs ...string) error

Chance of overriding global functions/variables by mistake

I don't think it's a good idea to bind functions to the global window object, there's a large chance that people will be overriding browser functionality by naming things the same as existing functionality.

Is there any way to prevent this by default? Maybe everything could be bound to a sub-object of window? So that it could be accessible through something like lorca.myFunction().

Exposing Chrome send method

First off, thank you @zserge for such a great project!
I'm wondering do you ever consider exposing Chrome send method as a public one?
This would allow multiple add-hoc scenarios using Chrome Dev Tools protocol. For instance, within on-demand auth flows it can be possible to open a window with auth form, then retrieve auth cookies and use them in http client's requests, or, in the opposite, open chrome window with prepopulated auth cookies, and so on and so force.

Replace Chrome Icon in Dock/Taskbar with Custom Icon?

I am really liking Lorca. But as I am trying to build a product I am wondering it if will be possible to replace the Chrome Logo with our own logo for icons in the macOS dock and I assume the same would be needed for Windows?

Cannot find chromium installed through Ubuntu Software store

Ubuntu Software store in 18.04 installs chromium binaries in a non-standard /snap directory.

Lorca only looks here on linux:

paths = []string{
	"/usr/bin/google-chrome-stable",
	"/usr/bin/google-chrome",
	"/usr/bin/chromium",
	"/usr/bin/chromium-browser",
}

If chromium is installed this way, you get this runtime error:

2019/05/15 23:28:33 fork/exec : no such file or directory
exit status 1

The /snap path would be a helpful addition for Ubuntu Software Center chromium downloads.

I worked around this problem by installing google-chrome-stable
https://linuxize.com/post/how-to-install-google-chrome-web-browser-on-ubuntu-18-04/

json: cannot unmarshal object into Go value of type string

I have HTML with text input and submit button which should pass the text input as an arg into the Javascript binding. It looks as follows:

<input type="text" name="MACADD" style="height:20px; width:210px">
<input type="submit" value="submit" onclick="JSBINDFUNC(MACADD)">

The JSBINDFUNC takes golang type string for input.
When I hit submit, it should be passing the text entered for MACADD as an arg into the JSBINDFUNC func.

However, I'm coming back with the err

exception":{"type":"string","value":"json: cannot unmarshal object into Go value of type string"}

Needing this object to become golang string.

You can copy/paste & run this to test:

package main

import (
    "fmt"
    "log"
    "net/url"

    "github.com/zserge/lorca"
)

func main() {
    ui, err := lorca.New("data:text/html,"+url.PathEscape(`
        <html>
                <form action="/action_page.php">
                    MAC Address:<br>
                    <input type="text" name="MACADD" style="height:20px; width:210px">
                    <input type="submit" value="Submit" onclick="JSBINDFUNC(MACADD)">
                </form> 
            </body>
        </html>
        `), "", 480, 320)
    if err != nil {
        log.Fatal(err)
    }
    //ui.Bind implemented @ https://github.com/zserge/lorca/blob/master/ui.go#L110
    ui.Bind("JSBINDFUNC", func(MAC string) {
        fmt.Println(MAC)
        return
    })
    defer ui.Close()
    <-ui.Done()
}

Bug: nil pointer interface.

I take nil pointer interface in Mac OS X:

installation:

$ go get -v github.com/zserge/lorca
github.com/zserge/lorca (download)
Fetching https://golang.org/x/net/websocket?go-get=1
Parsing meta tags from https://golang.org/x/net/websocket?go-get=1 (status code 200)
get "golang.org/x/net/websocket": found meta tag get.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at h
ttps://golang.org/x/net/websocket?go-get=1
get "golang.org/x/net/websocket": verifying non-authoritative meta tag
Fetching https://golang.org/x/net?go-get=1
Parsing meta tags from https://golang.org/x/net?go-get=1 (status code 200)
golang.org/x/net (download)
golang.org/x/net/websocket
github.com/zserge/lorca

sample code:

package main

import (
        "fmt"
	"github.com/zserge/lorca"
)

func main() {
	ui, _ := lorca.New("", "", 480, 320)  # <---- ui is nil pointer interface!
	fmt.Printf("%v\n", ui) 
	defer ui.Close()
}

result:

$ go run -v testcase8.go
command-line-arguments
<nil>
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x12b0c09]

goroutine 1 [running]:
main.main()
        /test/testcase8.go:15 +0xd9
exit status 2

Submit HTML form to func

I'm trying to submit HTML directly to a go func instead of using an embedded http server due to development requirements.

Here's an example of what I can do:

var inputform string = `
<html>
	<body>
		<form action="/action_page.php">
			<input type="text" name="userinput">
			<input type="submit" onclick="golangfunc(userinput.value)">
		</form>
	</body>
</html>
`

func main(){
	ui, err := lorca.New("data:text/html,"+url.PathEscape(inputform), "", 480, 320)
	ui.Bind("golangfunc", golangfunc)
	defer ui.Close()
	<-ui.Done()
}

func golangfunc(input string){
	fmt.Println(input)
}

I'd like to pass an HTML form instead of a single input value, but not sure how to do this. I have an arbitrary number of HTML input fields, as I am actually generating the HTML from XML data, and I need to submit the HTML data so that I can then generate XML.

go version 1.12 not allowed

when I use go version 1.12 and 1.12.3 build my exe,I cannot open my exe, when I double click exe nothing to show, then I use go version 1.11.3 window/amd64 build, then it works , I cant find why, hope an cool person to help me, thank you very much

Should be added more locate on Windows.

"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",

	paths := []string{
		"/usr/bin/google-chrome-stable",
		"/usr/bin/google-chrome",
		"/usr/bin/chromium",
		"/usr/bin/chromium-browser",
		"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
		"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
		"/Applications/Chromium.app/Contents/MacOS/Chromium",
		"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
		"C:/Users/" + os.Getenv("USERNAME") + "/AppData/Local/Google/Chrome/Application/chrome.exe",
	}

Should be added this line below.

Video stream with mediaDevices.getUserMedia - no access request pop-up?

Hello,

I'm trying to stream a USB camera in a GUI using lorca but I don't get the pop up requesting for access to the camera when the interface opens, so the video stream never starts. Is there a way to give the camera rights by default (I kind of understood that it's not allowed by the HTML 5 standard), to allow the pop-up, or to request access rights via a separate command?

I have attached my code below - the HTML video streaming part works fine when opening it in Chrome.

video_stream.txt

Thanks,
Michael

If chrome/Chromiom is not installed, what is supported fallback?

I have just downloaded today and have been trying out few snippets and modifying examples at work. It was working fine.

At home when I tried to explore it more, It failed.. Because being a firefox user, I haven't yet installed Google chrome on my freshly installed Fedora. I did have Brave Browser ( which is based on libchromium ) but example programs didn't pick it up for some reason.

So what I wanted to ask is,

  1. Is there any fallback for someone who doesn't have chrome installed at default location ( like portable chrome in windows, Or chromium based browser which have its own path )
  2. Is there any plan to support multiple backend for webview ( Edge for windows, Safari for Mac, Firefox on linux )

File Save Dialog

The README.md states "native OS dialogs are still possible via 3rd-party libraries".
Can anyone recommend any such library for implementing a file save dialog in Linux (or possibly Windows)?

security: Chrome debugging protocol is open to anyone on localhost

Hi. Lorca currently exposes all information about the UI to all processes on localhost, and allows any local process to hijack the UI.

https://peter.sh/experiments/chromium-command-line-switches/#remote-debugging-address

$ mkdir z
$ cd z
$ go mod init demo
go: creating new go.mod: module demo
$ curl https://raw.githubusercontent.com/zserge/lorca/master/examples/hello/main.go >main.go
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   408  100   408    0     0    542      0 --:--:-- --:--:-- --:--:--   541
$ go run main.go
go: finding github.com/zserge/lorca v0.1.6
go: downloading github.com/zserge/lorca v0.1.6
go: extracting github.com/zserge/lorca v0.1.6

As the attacker:

$ ss -ltnp |grep chrome
LISTEN   0         10                127.0.0.1:42381            0.0.0.0:*        users:(("chrome",pid=1703,fd=98))                                              
$ google-chrome http://127.0.0.1:42381
# observe the UI contents happily

I would recommend you switch to --remote-debugging-pipe: https://github.com/chromium/chromium/blob/d925e7f357d93b95631c22c47e2cc93b093dacc5/content/public/common/content_switches.cc#L700-L703

Opening new windows doesn't execute ui.Load

The app loads fine on first run but if I close the initial window and then click the icon in the dock (osx) it opens a new default chrome window without running ui.Load. The only way to reload the app is to start the app again-- which introduces another problem because it creates multiple instances of chrome. Ideally it would detect if the app is already open and either launch a new window or bring the existing window to the foreground. Excellent library btw, I think it will pair nicely with github.com/getlantern/systray.

Support Chromium based Microsoft Edge

I took the liberty of creating this issue so we can track and centralize discussion around supporting the upcoming Chromium engine based Microsoft Edge.

Microsoft's official announcement (archive.org copy) (PDF copy) (Gist markdown copy)

What

Today we’re announcing that we intend to adopt the Chromium open source project in the development of Microsoft Edge on the desktop to create better web compatibility for our customers and less fragmentation of the web for all web developers.

When

Over the next year or so, we’ll be making a technology change that happens “under the hood” for Microsoft Edge, gradually over time, and developed in the open so those of you who are interested can follow along.

My take

This is potentially great news for Lorca on Windows if future Edge provides the features that Lorca needs. Current version of Edge on Windows 10 spawns a private Edge session for me when running:

start shell:AppsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge -private https://github.com

image

But my understanding is that Lorca also relies on Chrome DevTools Protocol. I hope to see that available in the new Edge.

Pass JS variable to golang

package main

import (
	"fmt"
	"net/url"

	"github.com/zserge/lorca"
)

var (
	page_11 = `<html><p>test</p></html>`
)

func main() {
	ui, _ := lorca.New("data:text/html,"+url.PathEscape(page_11), "", 480, 320)
	njs := ui.Eval(`
                var t = "testvar"
                t;
        `)
	fmt.Println(njs)
}

This works, but return t; does not. How can I pass variables back to golang without calling them directly?

Lorca + Elm

Hi,

I really like the concept behind Lorca, and I am a big fan of Elm, so I have tried to put together a counter demo app with these two technologies.

go-elm-lorca-counter

At the moment, it only produces a binary for MacOs; but it should be possible to add scripts for other OSs in the future.

I hope a few other people will find this demo useful.

Olivier

  • In the London heatwave (today)-

lorca vs webview vs electron

I was wondering how this project differed from your webview and also electron.

Perhaps you can have a table on the README

No easy way to terminate whole application

I was trying to close my lorca app in two ways:

  1. By binding go function which runs os.Exit(0) and running it in js (actually it was vue, but I think that it doesn't matter)
  2. By running kill <my-app-ID-number>

Both ways terminated only code written in go, but rest of app (chromium UI layer) was still in its place.

I observed that after killing my app manually by clicking Ctrl + c in terminal output of ps aux | grep chromium was following: karol 9725 0.0 0.0 6208 888 pts/2 S+ 22:13 0:00 grep chromium, however by killing my app by kill <my-app-ID-number>, output of ps aux | grep chromium was following:

karol     9494  2.4  1.9 3012884 156584 pts/0  SLl  22:13   0:00 /usr/lib/chromium/chromium --show-component-extension-options --enable-gpu-rasterization --no-default-browser-check --disable-pings --media-router=0 --enable-remote-extensions --load-extension= --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-default-apps --disable-dev-shm-usage --disable-infobars --disable-extensions --disable-features=site-per-process --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --disable-translate --metrics-recording-only --no-first-run --safebrowsing-disable-auto-update --enable-automation --password-store=basic --use-mock-keychain --app=data:text/html,<html></html> --user-data-dir=/tmp/lorca025088096 --window-size=720,720 --class=Lorca --remote-debugging-port=0
karol     9508  0.0  0.0   5740  1772 pts/0    S    22:13   0:00 /usr/lib/chromium/chrome-sandbox /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca025088096
karol     9509  0.1  0.7 408188 60800 pts/0    SL   22:13   0:00 /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca025088096
karol     9511  0.0  0.1 408188 14264 pts/0    S    22:13   0:00 /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca025088096
karol     9534  1.0  1.4 1226304 117532 pts/0  SLl  22:13   0:00 /usr/lib/chromium/chromium --type=gpu-process --field-trial-handle=5158464758563543256,8617488245687844448,131072 --disable-features=site-per-process --disable-breakpad --enable-gpu-rasterization --user-data-dir=/tmp/lorca025088096 --gpu-preferences=KAAAAAAAAACAAAAAAQAAAAAAAAAAAGAAAAAAAAEAAAAIAAAAAAAAAAgAAAAAAAAA --service-request-channel-token=5379940991211926664
karol     9684  1.1  1.1 1389292 93324 pts/0   Sl   22:13   0:00 /usr/lib/chromium/chromium --type=renderer --disable-background-timer-throttling --disable-breakpad --enable-automation --field-trial-handle=5158464758563543256,8617488245687844448,131072 --disable-features=site-per-process --disable-gpu-compositing --service-pipe-token=921988823902182683 --lang=en-US --user-data-dir=/tmp/lorca025088096 --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --num-raster-threads=2 --enable-main-frame-before-activation --service-request-channel-token=921988823902182683 --renderer-client-id=5 --shared-files=v8_context_snapshot_data:100,v8_natives_data:101
karol     9725  0.0  0.0   6208   888 pts/2    S+   22:13   0:00 grep chromium

So technically go layer is an actual app, but UI layer isn't actually an app, but chromium process(es).
Can we "merge" these two layers to one my-app process?

Ctrl-t and ctrl-n open new browser window

On Windows, standard chrome shortcuts ctrl-t and ctrl-n open a new, empty browser window, which is probably not what any application writer wants.

If possible, they should be blocked. Better yet, it would be good if that was routed through logic in Go program so that user of library can decide if this should be blocked or allowed to proceed. If allowed to proceed, there should be a way to specify which html file or url to load.

Suggestions: 1) README example doesn't compile 2) Add intermediate example

  1. Perhaps make README 's example copy-pastable without compile errors like:
	ui, _ := lorca.New("", "", 480, 320)
	defer ui.Close()

	// Bind Go function to be available in JS. Go function may be long-running and
	// blocking - in JS it's represented with a Promise.
	ui.Bind("add", func(a, b int) int { return a + b })

	// Call JS function from Go. Functions may be asynchronous, i.e. return promises
	n := ui.Eval(`Math.random()`).Float()
	fmt.Println(n)

	// Call JS that calls Go and so on and so on...
	m := ui.Eval(`add(2, 3)`).Int()
	fmt.Println(m)

	// Wait for the browser window to be closed
	<-ui.Done()
  1. Perhaps adding an intermediate example between README's basic example and the full blown one in /example would help users grasp how to the library works. eg.:

image

	ui, _ := lorca.New("", "", 480, 320)
	defer ui.Close()

	ui.Load("data:text/html," + url.PathEscape(`
	<html>
	  <head><title>Calling Go from Js and Js from Go</title></head>
	  <body>

	  <h1>1 - Calling Go code from page's Javascript</h1>
	  <script>
	  function incrementFromGoCode(button) {
        // add() exists in Js because we called ui.Bind("add", func(){}) in Go
		add(parseInt(button.value), 1).then(function(valueFromGo){
			button.value = valueFromGo;
		});
	  }
	  </script>
	  Click to call Go: <input type="button" id="button1" value="0" onclick="incrementFromGoCode(this)">

	  <h1>2 - Calling Javascript from Go</h1>
	  <p>Value updated from Go: <span id="span1">0</span></p>
	  </body>
	</html>`))

	// Allows Js to call our Go function add()
	ui.Bind("add", func(a, b int) int { return a + b })

	// Calls Js to increment value in HTML every second
	go func() {
		for i := 0; ; i++ {
			ui.Eval(fmt.Sprintf("document.getElementById('span1').innerHTML = %d;", i))
			time.Sleep(1 * time.Second)
		}
	}()

	<-ui.Done()

Linux class name override

If someone adds a custom class arg it doesn't work because the default --class=Lorca is created after the customArgs are appended causing it to be used instead.

lorca/ui.go

Lines 77 to 81 in fc17d70

args = append(args, customArgs...)
args = append(args, "--remote-debugging-port=0")
if runtime.GOOS == "linux" {
args = append(args, "--class=Lorca")
}

Component pattern

Lora reduces complexity . Well done

I propose a simple design pattern for components in such a way that different components with their logic ( golang ) can be easily composed into larger applications.

One idea is a simple cqrs approach with every view model having a matching dataview.
This results in I pure unidirectional flow.
Golang components only need to subscribe to domain events.
Golang components only need to publish mutations using domain actions that then produce domain events.
You get react reflux without all the hassle. Will be deadly fast I suspect too.

This works hand in hand with asynchronous two way calls between chrome and golang

The only thing I am curious about is templating the components together. Maybe the maintainer has thoughts on this going forward ?

Read XSLT string and handle terminal output

I decided (many years ago) to create bonsole project (browser based console). It will deliver Firefox based terminal emulator (or something like that), library that handles http resoponse negotation, tool to set conditional task based on returned content (for example - it will run given command and if it return jpg image, it will be saved to file, but if given command returns text, it will print it or use as xmessage/zenity/kdialog parameter, etc. ) and client library.

This client library will checks if we have BONSOLE_SOME_ENV set up, providing Unix socket path and reads BONSOLE_XSLT_STRING or BONSOLE_XSLT_FILE_PATH to translate program's html output into string/terminal escape sequences. This library, if BONSOLE_SOME_ENV isn't set, it will also run nodejs or something to handle JavaScript.

I propose to realize library, which will run XSLT code to translate html output into string accessible by terminal (and possibly will run nodejs) in your project.

Why? To create rich console apps. LS Unix command could provide a full page, which links (anchors) to directories or (translated by library proposed by me) default output, or many different output. For example output of ls doesn't had to have colors and could looks like this:
directories:
.. . A B C
Images:
A.jpg, B.png, C.ico
Documents:
A.odt

Can I have multiple tabs with Lorca?

Can I have multiple tabs with Lorca? if not, may please suggest a solution to enhance lorca?
i am trying to implement a multiple page application, one page for one functionality.

ui.Eval does not return a value

Grabbing HTML value from document via Eval returns no value. Not sure if this is a bug or I have bad HTML. I do not get any runtime errors.

My code

package main

import (
	"fmt"
	"net/url"

	"github.com/zserge/lorca"
)

var (
	ui1        lorca.UI
	HTML_entry string = `
<html>
    <body>
        <input hidden type="text" name="MYVAR" value="testVal">
        <input type="submit" onclick="golangfunc()"
    </body>
</html>
`
)

func main() {
	ui1, _ = lorca.New("data:text/html,"+url.PathEscape(HTML_entry), "", 480, 320)
	ui1.Bind("golangfunc", golangfunc)
	defer ui1.Close()
	<-ui1.Done()
}

func golangfunc() {
	htmlvar := ui1.Eval(`document.getElementsByName('MYVAR').value`).String()
	fmt.Println(htmlvar)
}

undefined: FS

Getting when running the counter example or anything similar

# command-line-arguments
.\main.go:32:36: undefined: FS
ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()
	go http.Serve(ln, http.FileServer(FS)) // FS here is what undefined?
	ui.Load(fmt.Sprintf("http://%s", ln.Addr()))

Release version v0.1.8

Hi,

Currently go getting lorca without @master suffix downloads version v0.1.7, which is still affected by the panic bug fixed in #63.
Releasing the next version should fix this.

Thank you for your time.

Lorca vs webview

Sorry if this is the wrong place to ask, but just wondering, when would you suggest the use of Lorca vs webview?

Extra \r in chrome response

I'm on master of zserge/lorca. Just upgraded do go 1.12 (windows), so might be related to this, but I doubt it.

The problem:
When running lorca app, it worked fine before. But now it fails, because lorca.New("", "", 680, 820) returns not-nil error.

When debugging, I found that the regex

re := regexp.MustCompile(`^DevTools listening on (ws://.*)\n$`)

doesn't strip \r. So it fails later at config, err := NewConfig(url_, origin)
After changing the regex like this (maybe not ideal)

re := regexp.MustCompile(`^DevTools listening on (ws://[^\r\n]*)\r?\n$`)

it works well (at least it doesn't fail).


I'm not sure what changed and if that behaviour is dependent on go version or what, so asking here for thoughts.

Application dies after a few seconds

I compiled both the example and the following program on Linux and Windows. They run fine for a few seconds and then they exit automatically with no errors. Should they not stay running until I close the browser?

I am using Go version go1.11.2 and Chrome 70.0.3538.102 (Official Build) (64-bit)

package main

import (
"fmt"
"os"

"github.com/zserge/lorca"

)

func main() {

ui, err := lorca.New("", "", 480, 320)

if err != nil {
	fmt.Fprintf(os.Stderr, "fatal: %v\n", err)
	os.Exit(1)
}


defer ui.Close()

// Bind Go function to be available in JS. Go function may be long-running and
// blocking - in JS it's represented with a Promise.
ui.Bind("add", func(a, b int) int { return a + b })

// Call JS function from Go. Functions may be asynchronous, i.e. return promises
n := ui.Eval(`Math.random()`).Float()
fmt.Println(n)

// Call JS that calls Go and so on and so on...
m := ui.Eval(`add(2, 3)`).Int()
fmt.Println(m)

// Wait for the browser window to be closed
<-ui.Done()

}

How to use nodejs packages?

I guess you could probably bundle the nodejs app, then include it as asset in the go binary.

Any thoughts ?

Stability question

I understand Lorca does not ship with as much garbage as Electron because it uses an installed version of Chrome by the user instead of shipping with it's own version. How does it handle a situation where chrome is non-existent on the installed machine or chrome is too old on the installed machine causing some things in my web application to not function right?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.