diff --git a/locate_chromium.go b/locate_chromium.go new file mode 100644 index 0000000..93f6562 --- /dev/null +++ b/locate_chromium.go @@ -0,0 +1,53 @@ +package lorca + +import ( + "os" + "runtime" +) + +// ChromeExecutable returns a string which points to the preferred Chromium +// executable file. +var ChromiumExecutable = LocateChromium + +// LocateChromium returns a path to the Chromium binary, or an empty string if +// the Chromium installation is not found. +func LocateChromium() string { + + // If env variable "LORCACHROME" specified and it exists + if path, ok := os.LookupEnv("LORCACHROMIUM"); ok { + if _, err := os.Stat(path); err == nil { + return path + } + } + + var paths []string + switch runtime.GOOS { + case "darwin": + paths = []string{ + "/Applications/Chromium.app/Contents/MacOS/Chromium", + "/usr/bin/chromium", + "/usr/bin/chromium-browser", + } + case "windows": + paths = []string{ + os.Getenv("LocalAppData") + "/Chromium/Application/chrome.exe", + os.Getenv("ProgramFiles") + "/Chromium/Application/chrome.exe", + os.Getenv("ProgramFiles(x86)") + "/Chromium/Application/chrome.exe", + } + default: + paths = []string{ + "/usr/bin/chromium", + "/usr/bin/chromium-browser", + "/snap/bin/chromium", + } + } + + for _, path := range paths { + if _, err := os.Stat(path); os.IsNotExist(err) { + continue + } + return path + } + return "" +} + diff --git a/locate_edge.go b/locate_edge.go new file mode 100644 index 0000000..fda19d9 --- /dev/null +++ b/locate_edge.go @@ -0,0 +1,49 @@ +package lorca + +import ( + "os" + "runtime" +) + +// EdgeExecutable returns a string which points to the preferred Edge +// executable file. +var EdgeExecutable = LocateEdge + +// LocateEdge returns a path to the Edge binary, or an empty string if +// Edge installation is not found. +func LocateEdge() string { + + // If env variable "LORCACHROME" specified and it exists + if path, ok := os.LookupEnv("LORCAEDGE"); ok { + if _, err := os.Stat(path); err == nil { + return path + } + } + + var paths []string + switch runtime.GOOS { + case "darwin": + paths = []string{ + "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge", + } + case "windows": + paths = []string{ + os.Getenv("ProgramFiles") + "/Microsoft/Edge/Application/msedge.exe", + os.Getenv("ProgramFiles(x86)") + "/Microsoft/Edge/Application/msedge.exe", + } + default: + paths = []string{ + "/usr/bin/microsoft-edge-stable", + "/usr/bin/microsoft-edge", + } + } + + for _, path := range paths { + if _, err := os.Stat(path); os.IsNotExist(err) { + continue + } + return path + } + return "" +} + diff --git a/locate_google_chrome.go b/locate_google_chrome.go new file mode 100644 index 0000000..abcc29e --- /dev/null +++ b/locate_google_chrome.go @@ -0,0 +1,52 @@ +package lorca + +import ( + "os" + "runtime" +) + +// GoogleChromeExecutable returns a string which points to the preferred +// Google Chrome executable file. +var GoogleChromeExecutable = LocateGoogleChrome + +// LocateGoogleChrome returns a path to the Google Chrome binary, or an empty +// string if the Google Chrome installation is not found. +func LocateGoogleChrome() string { + + // If env variable "LORCACHROME" specified and it exists + if path, ok := os.LookupEnv("LORCAGOOGLECHROME"); ok { + if _, err := os.Stat(path); err == nil { + return path + } + } + + var paths []string + switch runtime.GOOS { + case "darwin": + paths = []string{ + "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", + "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary", + "/usr/bin/google-chrome-stable", + "/usr/bin/google-chrome", + } + case "windows": + paths = []string{ + os.Getenv("LocalAppData") + "/Google/Chrome/Application/chrome.exe", + os.Getenv("ProgramFiles") + "/Google/Chrome/Application/chrome.exe", + os.Getenv("ProgramFiles(x86)") + "/Google/Chrome/Application/chrome.exe", + } + default: + paths = []string{ + "/usr/bin/google-chrome-stable", + "/usr/bin/google-chrome", + } + } + + for _, path := range paths { + if _, err := os.Stat(path); os.IsNotExist(err) { + continue + } + return path + } + return "" +} diff --git a/ui_html5.go b/ui_html5.go new file mode 100644 index 0000000..ac5a5ce --- /dev/null +++ b/ui_html5.go @@ -0,0 +1,84 @@ +package lorca + +import ( + "fmt" + "io/ioutil" +) + +var AdditionalChromiumArgs = []string{ + "--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-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", + "--disable-windows10-custom-titlebar", + "--metrics-recording-only", + "--no-first-run", + "--no-default-browser-check", + "--safebrowsing-disable-auto-update", + "--password-store=basic", + "--use-mock-keychain", +} + +// NewHtml5 returns a new HTML5 UI for the given executable URL, user profile +// directory, window size and other options passed to the browser engine. If +// URL is an empty string - a blank page is displayed. If user profile directory +// is an empty string - a temporary directory is created and it will be removed on +// ui.Close(). You might want to use "--headless" custom CLI argument to test +// your UI code. +func NewHtml5(executable, url, dir string, width, height int, additionalArgs ...string) (UI, error) { + if url == "" { + url = "data:text/html," + } + tmpDir := "" + if dir == "" { + name, err := ioutil.TempDir("", "lorca") + if err != nil { + return nil, err + } + dir, tmpDir = name, name + } + args := append([]string{}, fmt.Sprintf("--app=%s", url)) + args = append(args, fmt.Sprintf("--user-data-dir=%s", dir)) + args = append(args, fmt.Sprintf("--window-size=%d,%d", width, height)) + args = append(args, additionalArgs...) + args = append(args, "--remote-debugging-port=0") + + chrome, err := newChromeWithArgs(executable, args...) + done := make(chan struct{}) + if err != nil { + return nil, err + } + + go func() { + chrome.cmd.Wait() + close(done) + }() + return &ui{chrome: chrome, done: done, tmpDir: tmpDir}, nil +} + +// NewChromium returns a new Chromium HTML5 UI. +func NewChromium(url, dir string, width, height int, additionalArgs ...string) (UI, error) { + return NewHtml5(ChromiumExecutable(), url, dir, width, height, additionalArgs...) +} + +// NewEdge returns a new Edge HTML5 UI. +func NewEdge(url, dir string, width, height int, additionalArgs ...string) (UI, error) { + return NewHtml5(EdgeExecutable(), url, dir, width, height, additionalArgs...) +} + +// NewGoogleChrome returns a new Google Chrome HTML5 UI. +func NewGoogleChrome(url, dir string, width, height int, additionalArgs ...string) (UI, error) { + return NewHtml5(GoogleChromeExecutable(), url, dir, width, height, additionalArgs...) +}