Compare commits

..

4 Commits
4.0.0 ... 4.1.0

Author SHA1 Message Date
Julien Neuhart
571c3e04c4 adding form field web fonts timeout 2019-02-01 09:40:16 +01:00
Sergei Opletaev
f9fb97a572 Fix for #44 promise wait for fonts (#45)
`runtime.ExceptionDetails: Uncaught exception at 4:47: SyntaxError: Unexpected token %`
2019-02-01 09:21:02 +01:00
Julien Neuhart
e6484bb2d5 Trigger GitHub documentation 2019-01-28 15:56:13 +01:00
Julien Neuhart
19f51fdc1f fixing PHP documentation 2019-01-28 15:36:59 +01:00
16 changed files with 111 additions and 53 deletions

View File

@@ -187,6 +187,9 @@ You may also use *remote* paths for Google fonts, images and so on.
> If you want to install fonts directly in the Gotenberg Docker image, > If you want to install fonts directly in the Gotenberg Docker image,
> see to the [fonts section](#fonts). > see to the [fonts section](#fonts).
> For web fonts, there is a timeout of 500ms by default. You may update
> this value thanks to the form field `webFontsTimeout`.
### cURL ### cURL
```bash ```bash

View File

@@ -52,5 +52,5 @@ $client = new Client('http://localhost:3000', new \Http\Adapter\Guzzle6\Client()
$request = new URLRequest('https://google.com'); $request = new URLRequest('https://google.com');
$request->setMargins(Request::NO_MARGINS); $request->setMargins(Request::NO_MARGINS);
$dest = "result.pdf"; $dest = "result.pdf";
$filename = $client->store($request, $dest); $client->store($request, $dest);
``` ```

View File

@@ -66,5 +66,5 @@ $markdowns = [
]; ];
$request = new MarkdownRequest($index, $markdowns); $request = new MarkdownRequest($index, $markdowns);
$dest = "result.pdf"; $dest = "result.pdf";
$filename = $client->store($request, $dest); $client->store($request, $dest);
``` ```

View File

@@ -66,7 +66,7 @@ $files = [
]; ];
$request = new OfficeRequest($files); $request = new OfficeRequest($files);
$dest = "result.pdf"; $dest = "result.pdf";
$filename = $client->store($request, $dest); $client->store($request, $dest);
``` ```
## Orientation ## Orientation
@@ -114,5 +114,5 @@ $files = [
$request = new OfficeRequest($files); $request = new OfficeRequest($files);
$request->setLandscape(true); $request->setLandscape(true);
$dest = "result.pdf"; $dest = "result.pdf";
$filename = $client->store($request, $dest); $client->store($request, $dest);
``` ```

View File

@@ -49,5 +49,5 @@ $files = [
]; ];
$request = new MergeRequest($files); $request = new MergeRequest($files);
$dest = "result.pdf"; $dest = "result.pdf";
$filename = $client->store($request, $dest); $client->store($request, $dest);
``` ```

View File

@@ -363,6 +363,9 @@ are on the same level as the <code>index.html</code> file.</p>
<blockquote> <blockquote>
<p>If you want to install fonts directly in the Gotenberg Docker image, <p>If you want to install fonts directly in the Gotenberg Docker image,
see to the <a href="#fonts">fonts section</a>.</p> see to the <a href="#fonts">fonts section</a>.</p>
<p>For web fonts, there is a timeout of 500ms by default. You may update
this value thanks to the form field <code>webFontsTimeout</code>.</p>
</blockquote> </blockquote>
<h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.assets.c_url" href="#html.assets.c_url"> <h3 class="Heading"><a class="Anchor" aria-hidden="true" id="html.assets.c_url" href="#html.assets.c_url">
@@ -545,7 +548,7 @@ $client = new Client(&#39;http://localhost:3000&#39;, new \Http\Adapter\Guzzle6\
$request = new URLRequest(&#39;https://google.com&#39;); $request = new URLRequest(&#39;https://google.com&#39;);
$request-&gt;setMargins(Request::NO_MARGINS); $request-&gt;setMargins(Request::NO_MARGINS);
$dest = &#34;result.pdf&#34;; $dest = &#34;result.pdf&#34;;
$filename = $client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
</div> </div>
@@ -622,7 +625,7 @@ $markdowns = [
]; ];
$request = new MarkdownRequest($index, $markdowns); $request = new MarkdownRequest($index, $markdowns);
$dest = &#34;result.pdf&#34;; $dest = &#34;result.pdf&#34;;
$filename = $client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
</div> </div>
@@ -704,7 +707,7 @@ $files = [
]; ];
$request = new OfficeRequest($files); $request = new OfficeRequest($files);
$dest = &#34;result.pdf&#34;; $dest = &#34;result.pdf&#34;;
$filename = $client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
<h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.orientation" href="#office.orientation"> <h2 class="Heading"><a class="Anchor" aria-hidden="true" id="office.orientation" href="#office.orientation">
@@ -757,7 +760,7 @@ $files = [
$request = new OfficeRequest($files); $request = new OfficeRequest($files);
$request-&gt;setLandscape(true); $request-&gt;setLandscape(true);
$dest = &#34;result.pdf&#34;; $dest = &#34;result.pdf&#34;;
$filename = $client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
</div> </div>
@@ -818,7 +821,7 @@ $files = [
]; ];
$request = new MergeRequest($files); $request = new MergeRequest($files);
$dest = &#34;result.pdf&#34;; $dest = &#34;result.pdf&#34;;
$filename = $client-&gt;store($request, $dest); $client-&gt;store($request, $dest);
</pre> </pre>
</div> </div>

View File

@@ -47,5 +47,10 @@ func convertHTML(c echo.Context) error {
return hijackErr(err, r) return hijackErr(err, r)
} }
p.Landscape = landscape p.Landscape = landscape
chromeWebFontsTimeout, err := r.webFontsTimeout()
if err != nil {
return hijackErr(err, r)
}
p.WebFontsTimeout = chromeWebFontsTimeout
return print(c, p, r) return print(c, p, r)
} }

View File

@@ -46,5 +46,10 @@ func convertMarkdown(c echo.Context) error {
return hijackErr(err, r) return hijackErr(err, r)
} }
p.Landscape = landscape p.Landscape = landscape
chromeWebFontsTimeout, err := r.webFontsTimeout()
if err != nil {
return hijackErr(err, r)
}
p.WebFontsTimeout = chromeWebFontsTimeout
return print(c, p, r) return print(c, p, r)
} }

View File

@@ -13,15 +13,16 @@ import (
) )
const ( const (
remoteURL string = "remoteURL" remoteURL string = "remoteURL"
webhookURL string = "webhookURL" webhookURL string = "webhookURL"
paperWidth string = "paperWidth" paperWidth string = "paperWidth"
paperHeight string = "paperHeight" paperHeight string = "paperHeight"
marginTop string = "marginTop" marginTop string = "marginTop"
marginBottom string = "marginBottom" marginBottom string = "marginBottom"
marginLeft string = "marginLeft" marginLeft string = "marginLeft"
marginRight string = "marginRight" marginRight string = "marginRight"
landscape string = "landscape" landscape string = "landscape"
webFontsTimeout string = "webFontsTimeout"
) )
// resource facilitates storing and accessing // resource facilitates storing and accessing
@@ -42,6 +43,7 @@ func newResource(c echo.Context) (*resource, error) {
v[marginLeft] = c.FormValue(marginLeft) v[marginLeft] = c.FormValue(marginLeft)
v[marginRight] = c.FormValue(marginRight) v[marginRight] = c.FormValue(marginRight)
v[landscape] = c.FormValue(landscape) v[landscape] = c.FormValue(landscape)
v[webFontsTimeout] = c.FormValue(webFontsTimeout)
dirPath, err := rand.Get() dirPath, err := rand.Get()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -190,5 +192,17 @@ func (r *resource) remoteURL() (string, error) {
return r.values[remoteURL], nil return r.values[remoteURL], nil
} }
func (r *resource) webFontsTimeout() (int64, error) {
webFontsTimeoutStr := r.values[webFontsTimeout]
if webFontsTimeoutStr == "" {
return 500, nil
}
timeout, err := strconv.ParseInt(webFontsTimeoutStr, 10, 64)
if err != nil {
return 500, fmt.Errorf("web fonts timeout: %v", err)
}
return timeout, nil
}
func (r *resource) webhookURL() string { return r.values[webhookURL] } func (r *resource) webhookURL() string { return r.values[webhookURL] }
func (r *resource) removeAll() error { return os.RemoveAll(r.dirPath) } func (r *resource) removeAll() error { return os.RemoveAll(r.dirPath) }

View File

@@ -47,5 +47,10 @@ func convertURL(c echo.Context) error {
return hijackErr(err, r) return hijackErr(err, r)
} }
p.Landscape = landscape p.Landscape = landscape
chromeWebFontsTimeout, err := r.webFontsTimeout()
if err != nil {
return hijackErr(err, r)
}
p.WebFontsTimeout = chromeWebFontsTimeout
return print(c, p, r) return print(c, p, r)
} }

View File

@@ -18,17 +18,18 @@ import (
// HTML facilitates HTML to PDF conversion. // HTML facilitates HTML to PDF conversion.
type HTML struct { type HTML struct {
Context context.Context Context context.Context
URL string URL string
HeaderHTML string HeaderHTML string
FooterHTML string FooterHTML string
PaperWidth float64 PaperWidth float64
PaperHeight float64 PaperHeight float64
MarginTop float64 MarginTop float64
MarginBottom float64 MarginBottom float64
MarginLeft float64 MarginLeft float64
MarginRight float64 MarginRight float64
Landscape bool Landscape bool
WebFontsTimeout int64
} }
const defaultHeaderFooterHTML string = "<html><head></head><body></body></html>" const defaultHeaderFooterHTML string = "<html><head></head><body></body></html>"
@@ -103,14 +104,17 @@ func (html *HTML) Print(destination string) error {
return fmt.Errorf("waiting for page loading: %v", err) return fmt.Errorf("waiting for page loading: %v", err)
} }
// inject a script to make sure web fonts are loaded. // inject a script to make sure web fonts are loaded.
script := `new Promise((resolve, reject) => { script := fmt.Sprintf(`new Promise((resolve, reject) => {
document.fonts.ready.then(function () { document.fonts.ready.then(function () {
resolve('fonts loaded'); resolve('fonts loaded');
}); });
setTimeout(resolve.bind(resolve, 'timeout'), %.0f); setTimeout(resolve.bind(resolve, 'timeout'), %d);
});` });`, html.WebFontsTimeout)
scriptArg := runtime.NewEvaluateArgs(script).SetAwaitPromise(true) scriptArg := runtime.NewEvaluateArgs(script).SetAwaitPromise(true)
returnObj, _ := c.Runtime.Evaluate(html.Context, scriptArg) returnObj, _ := c.Runtime.Evaluate(html.Context, scriptArg)
if returnObj.ExceptionDetails != nil {
return fmt.Errorf("script evaluated with exception: %+v", returnObj.ExceptionDetails)
}
loadFontsResult := string(returnObj.Result.Value) loadFontsResult := string(returnObj.Result.Value)
if strings.Contains(loadFontsResult, "timeout") { if strings.Contains(loadFontsResult, "timeout") {
return errors.New("timed out loading fonts") return errors.New("timed out loading fonts")

View File

@@ -15,17 +15,18 @@ import (
// Markdown facilitates Markdown to PDF conversion. // Markdown facilitates Markdown to PDF conversion.
type Markdown struct { type Markdown struct {
Context context.Context Context context.Context
TemplatePath string TemplatePath string
HeaderHTML string HeaderHTML string
FooterHTML string FooterHTML string
PaperWidth float64 PaperWidth float64
PaperHeight float64 PaperHeight float64
MarginTop float64 MarginTop float64
MarginBottom float64 MarginBottom float64
MarginLeft float64 MarginLeft float64
MarginRight float64 MarginRight float64
Landscape bool Landscape bool
WebFontsTimeout int64
html *HTML html *HTML
} }
@@ -52,6 +53,7 @@ func (md *Markdown) Print(destination string) error {
md.html.MarginLeft = md.MarginLeft md.html.MarginLeft = md.MarginLeft
md.html.MarginRight = md.MarginRight md.html.MarginRight = md.MarginRight
md.html.Landscape = md.Landscape md.html.Landscape = md.Landscape
md.html.WebFontsTimeout = md.WebFontsTimeout
tmpl, err := template. tmpl, err := template.
New(filepath.Base(md.TemplatePath)). New(filepath.Base(md.TemplatePath)).
Funcs(template.FuncMap{"toHTML": toHTML}). Funcs(template.FuncMap{"toHTML": toHTML}).

View File

@@ -13,15 +13,16 @@ import (
) )
const ( const (
remoteURL string = "remoteURL" remoteURL string = "remoteURL"
webhookURL string = "webhookURL" webhookURL string = "webhookURL"
paperWidth string = "paperWidth" paperWidth string = "paperWidth"
paperHeight string = "paperHeight" paperHeight string = "paperHeight"
marginTop string = "marginTop" marginTop string = "marginTop"
marginBottom string = "marginBottom" marginBottom string = "marginBottom"
marginLeft string = "marginLeft" marginLeft string = "marginLeft"
marginRight string = "marginRight" marginRight string = "marginRight"
landscape string = "landscape" landscape string = "landscape"
webFontsTimeout string = "webFontsTimeout"
) )
var ( var (
@@ -75,6 +76,7 @@ type ChromeRequest interface {
SetPaperSize(size [2]float64) SetPaperSize(size [2]float64)
SetMargins(margins [4]float64) SetMargins(margins [4]float64)
SetLandscape(isLandscape bool) SetLandscape(isLandscape bool)
SetWebFontsTimeout(timeout int64)
} }
// UnoconvRequest is a type for sending // UnoconvRequest is a type for sending

View File

@@ -78,6 +78,11 @@ func (html *HTMLRequest) SetLandscape(isLandscape bool) {
html.values[landscape] = strconv.FormatBool(isLandscape) html.values[landscape] = strconv.FormatBool(isLandscape)
} }
// SetWebFontsTimeout sets webFontsTimeout form field.
func (html *HTMLRequest) SetWebFontsTimeout(timeout int64) {
html.values[webFontsTimeout] = strconv.FormatInt(timeout, 10)
}
func (html *HTMLRequest) getPostURL() string { func (html *HTMLRequest) getPostURL() string {
return "/convert/html" return "/convert/html"
} }

View File

@@ -88,6 +88,11 @@ func (markdown *MarkdownRequest) SetLandscape(isLandscape bool) {
markdown.values[landscape] = strconv.FormatBool(isLandscape) markdown.values[landscape] = strconv.FormatBool(isLandscape)
} }
// SetWebFontsTimeout sets webFontsTimeout form field.
func (markdown *MarkdownRequest) SetWebFontsTimeout(timeout int64) {
markdown.values[webFontsTimeout] = strconv.FormatInt(timeout, 10)
}
func (markdown *MarkdownRequest) getPostURL() string { func (markdown *MarkdownRequest) getPostURL() string {
return "/convert/markdown" return "/convert/markdown"
} }

View File

@@ -63,6 +63,11 @@ func (url *URLRequest) SetLandscape(isLandscape bool) {
url.values[landscape] = strconv.FormatBool(isLandscape) url.values[landscape] = strconv.FormatBool(isLandscape)
} }
// SetWebFontsTimeout sets webFontsTimeout form field.
func (url *URLRequest) SetWebFontsTimeout(timeout int64) {
url.values[webFontsTimeout] = strconv.FormatInt(timeout, 10)
}
func (url *URLRequest) getPostURL() string { func (url *URLRequest) getPostURL() string {
return "/convert/url" return "/convert/url"
} }