mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
feat(chromium): always inject paint-callback polyfill to cover waitDelay users
This commit is contained in:
@@ -308,7 +308,6 @@ func (b *chromiumBrowser) Healthy(logger *slog.Logger) bool {
|
||||
func (b *chromiumBrowser) pdf(ctx context.Context, logger *slog.Logger, url, outputPath string, options PdfOptions) error {
|
||||
// Note: no error wrapping because it leaks on errors we want to display to
|
||||
// the end user.
|
||||
installPaintPolyfill := options.WaitForExpression != "" || options.WaitForSelector != ""
|
||||
return b.do(ctx, logger, url, options.Options, chromedp.Tasks{
|
||||
network.Enable(),
|
||||
fetch.Enable(),
|
||||
@@ -318,7 +317,7 @@ func (b *chromiumBrowser) pdf(ctx context.Context, logger *slog.Logger, url, out
|
||||
disableJavaScriptActionFunc(logger, b.arguments.disableJavaScript),
|
||||
setCookiesActionFunc(logger, options.Cookies),
|
||||
userAgentOverride(logger, options.UserAgent),
|
||||
injectPaintCallbacksPolyfillActionFunc(logger, installPaintPolyfill),
|
||||
injectPaintCallbacksPolyfillActionFunc(logger),
|
||||
navigateActionFunc(logger, url, options.SkipNetworkIdleEvent, options.SkipNetworkAlmostIdleEvent),
|
||||
hideDefaultWhiteBackgroundActionFunc(logger, options.OmitBackground, options.PrintBackground),
|
||||
forceExactColorsActionFunc(logger, options.PrintBackground),
|
||||
@@ -336,7 +335,6 @@ func (b *chromiumBrowser) pdf(ctx context.Context, logger *slog.Logger, url, out
|
||||
func (b *chromiumBrowser) screenshot(ctx context.Context, logger *slog.Logger, url, outputPath string, options ScreenshotOptions) error {
|
||||
// Note: no error wrapping because it leaks on errors we want to display to
|
||||
// the end user.
|
||||
installPaintPolyfill := options.WaitForExpression != "" || options.WaitForSelector != ""
|
||||
return b.do(ctx, logger, url, options.Options, chromedp.Tasks{
|
||||
network.Enable(),
|
||||
fetch.Enable(),
|
||||
@@ -346,7 +344,7 @@ func (b *chromiumBrowser) screenshot(ctx context.Context, logger *slog.Logger, u
|
||||
disableJavaScriptActionFunc(logger, b.arguments.disableJavaScript),
|
||||
setCookiesActionFunc(logger, options.Cookies),
|
||||
userAgentOverride(logger, options.UserAgent),
|
||||
injectPaintCallbacksPolyfillActionFunc(logger, installPaintPolyfill),
|
||||
injectPaintCallbacksPolyfillActionFunc(logger),
|
||||
navigateActionFunc(logger, url, options.SkipNetworkIdleEvent, options.SkipNetworkAlmostIdleEvent),
|
||||
hideDefaultWhiteBackgroundActionFunc(logger, options.OmitBackground, true),
|
||||
forceExactColorsActionFunc(logger, true),
|
||||
|
||||
@@ -124,15 +124,14 @@ const paintCallbacksPolyfill = `
|
||||
|
||||
// injectPaintCallbacksPolyfillActionFunc installs the
|
||||
// [paintCallbacksPolyfill] via [page.AddScriptToEvaluateOnNewDocument]
|
||||
// so that it runs before any user script on the navigated page. When
|
||||
// install is false the action is a no-op and the page keeps the native
|
||||
// rAF, ResizeObserver, and IntersectionObserver implementations.
|
||||
func injectPaintCallbacksPolyfillActionFunc(logger *slog.Logger, install bool) chromedp.ActionFunc {
|
||||
// so that it runs before any user script on the navigated page. The
|
||||
// shim is installed unconditionally: the native rAF, ResizeObserver,
|
||||
// and IntersectionObserver APIs do not fire during Chromium's
|
||||
// headless-print render, so replacing them with timer-backed
|
||||
// implementations either restores the behavior the page expects or has
|
||||
// no effect when the page never calls them.
|
||||
func injectPaintCallbacksPolyfillActionFunc(logger *slog.Logger) chromedp.ActionFunc {
|
||||
return func(ctx context.Context) error {
|
||||
if !install {
|
||||
logger.DebugContext(ctx, "paint-callbacks polyfill not requested")
|
||||
return nil
|
||||
}
|
||||
logger.DebugContext(ctx, "inject paint-callbacks polyfill")
|
||||
_, err := page.AddScriptToEvaluateOnNewDocument(paintCallbacksPolyfill).Do(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -195,7 +195,7 @@ Feature: /forms/chromium/convert/html
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (paint-callback polyfill fires rAF / ResizeObserver / IntersectionObserver when waitForExpression is set)
|
||||
Scenario: POST /forms/chromium/convert/html (paint-callback polyfill fires rAF / ResizeObserver / IntersectionObserver with waitForExpression)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/paint-callbacks-html/index.html | file |
|
||||
@@ -219,14 +219,30 @@ Feature: /forms/chromium/convert/html
|
||||
io-fired
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (paint-callback polyfill skipped without a readiness signal)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| LOG_LEVEL | debug |
|
||||
Scenario: POST /forms/chromium/convert/html (paint-callback polyfill fires rAF / ResizeObserver / IntersectionObserver with waitDelay and emulatedMediaType=print)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| files | testdata/paint-callbacks-html/index.html | file |
|
||||
| waitDelay | 3s | field |
|
||||
| emulatedMediaType | print | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| paint-callbacks polyfill not requested |
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
raf-fired
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
ro-fired
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
io-fired
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Wait For Selector)
|
||||
Given I have a default Gotenberg container
|
||||
|
||||
Reference in New Issue
Block a user