diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f128f3..5fe31d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## Unreleased + +### Added + +- Extend `chrome_args` to allow removal of conflicting default args. Allows for use cases which were previously blocked by defaults such as rendering WebGL images. See #314 (@walter) + ## [1.16.0] - 2024-06-25 ### Changed diff --git a/lib/chromic_pdf.ex b/lib/chromic_pdf.ex index 4626b58..5ed9085 100644 --- a/lib/chromic_pdf.ex +++ b/lib/chromic_pdf.ex @@ -278,6 +278,24 @@ defmodule ChromicPDF do [chrome_args: "--font-render-hinting=none"] end + In some cases, chromic_pdf's default args may conflict with the ones you would like to add. + + E.g. `--disable-gpu` + + The problem is that you can't simply override them like so: + + E.g. in default args within chromic_pdf's code, `--disable-gpu` and then + passing `chrome_args: "--enable-gpu"` won't work. + + In this case, use Keyword form of the `:chrome_args` option which + allows targeted removing of problematic default args so that they don't + disrupt your chrome configuration. + + defp chromic_pdf_opts do + [chrome_args: [append: "--headless=new --angle=swiftshader", + remove: ["--headless", "--disable-gpu"]]] + end + The `:chrome_executable` option allows to specify a custom Chrome/Chromium executable. defp chromic_pdf_opts do diff --git a/lib/chromic_pdf/pdf/chrome_runner.ex b/lib/chromic_pdf/pdf/chrome_runner.ex index 36d36a7..c848cb8 100644 --- a/lib/chromic_pdf/pdf/chrome_runner.ex +++ b/lib/chromic_pdf/pdf/chrome_runner.ex @@ -148,13 +148,28 @@ defmodule ChromicPDF.ChromeRunner do defp args(extra, opts) do default_args() |> append_if("--no-sandbox", no_sandbox?(opts)) - |> append_if(to_string(opts[:chrome_args]), !!opts[:chrome_args]) + |> apply_chrome_args(opts[:chrome_args]) |> Kernel.++(List.wrap(extra)) |> append_if("2>/dev/null 3<&0 4>&1", discard_stderr?(opts)) end defp append_if(list, _value, false), do: list - defp append_if(list, value, true), do: list ++ [value] + defp append_if(list, value, true), do: list ++ List.wrap(value) + + defp apply_chrome_args(list, nil), do: list + + defp apply_chrome_args(list, chrome_args) when is_binary(chrome_args) do + append_if(list, chrome_args, true) + end + + defp apply_chrome_args(list, extended) when is_list(extended) do + conflicting = List.wrap(Keyword.get(extended, :remove, [])) + append = List.wrap(Keyword.get(extended, :append, [])) + + list + |> Enum.reject(&Enum.member?(conflicting, &1)) + |> append_if(append, true) + end defp no_sandbox?(opts), do: Keyword.get(opts, :no_sandbox, false) defp discard_stderr?(opts), do: Keyword.get(opts, :discard_stderr, true) diff --git a/lib/chromic_pdf/supervisor.ex b/lib/chromic_pdf/supervisor.ex index da77191..27ff301 100644 --- a/lib/chromic_pdf/supervisor.ex +++ b/lib/chromic_pdf/supervisor.ex @@ -220,13 +220,17 @@ defmodule ChromicPDF.Supervisor do @type ghostscript_pool_option :: {:size, non_neg_integer()} + @type extended_chrome_args :: [ + {:append, binary() | [binary()]} | {:remove, binary() | [binary()]} + ] + @typedoc """ These options apply to local Chrome instances only. """ @type local_chrome_option :: {:no_sandbox, boolean()} | {:discard_stderr, boolean()} - | {:chrome_args, binary()} + | {:chrome_args, binary() | extended_chrome_args()} | {:chrome_executable, binary()} @typedoc """