1+ // Copyright 2019-2025 Chris Mohan, Jaben Cargman
2+ // and GotenbergSharpApiClient Contributors
3+ //
4+ // Licensed under the Apache License, Version 2.0 (the "License");
5+ // you may not use this file except in compliance with the License.
6+ // You may obtain a copy of the License at
7+ //
8+ // http://www.apache.org/licenses/LICENSE-2.0
9+ //
10+ // Unless required by applicable law or agreed to in writing, software
11+ // distributed under the License is distributed on an "AS IS" BASIS,
12+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ // See the License for the specific language governing permissions and
14+ // limitations under the License.
15+
16+ using Newtonsoft . Json . Linq ;
17+
18+ namespace Gotenberg . Sharp . API . Client . Domain . Builders . Faceted ;
19+
20+ public sealed class HtmlConversionBehaviorBuilder
21+ {
22+ private readonly HtmlConversionBehaviors _htmlConversionBehaviors ;
23+
24+ internal HtmlConversionBehaviorBuilder ( HtmlConversionBehaviors htmlConversionBehaviors )
25+ {
26+ _htmlConversionBehaviors = htmlConversionBehaviors ;
27+ }
28+
29+ /// <summary>
30+ /// Sets the wait duration when loading an HTML document before converting it to PDF
31+ /// </summary>
32+ /// <param name="seconds"></param>
33+ /// <returns></returns>
34+ /// <remarks>Prefer <see cref="SetBrowserWaitExpression" /> over waitDelay.</remarks>
35+ public HtmlConversionBehaviorBuilder SetBrowserWaitDelay ( int seconds )
36+ {
37+ if ( seconds < 0 )
38+ {
39+ throw new ArgumentOutOfRangeException ( nameof ( seconds ) , "Wait delay must be zero or positive." ) ;
40+ }
41+
42+ _htmlConversionBehaviors . WaitDelay = $ "{ seconds } s";
43+
44+ return this ;
45+ }
46+
47+ /// <summary>
48+ /// Sets a java-script expression to wait before converting an HTML document to PDF until it returns true
49+ /// </summary>
50+ /// <param name="expression">The expression to set</param>
51+ /// <returns></returns>
52+ /// <remarks>Prefer this option over waitDelay.</remarks>
53+ /// <example>SetBrowserWaitExpression("window.status === 'ready'")</example>
54+ /// <exception cref="InvalidOperationException"></exception>
55+ public HtmlConversionBehaviorBuilder SetBrowserWaitExpression ( string expression )
56+ {
57+ if ( expression . IsNotSet ( ) )
58+ {
59+ throw new ArgumentException ( "expression cannot be null or empty" , nameof ( expression ) ) ;
60+ }
61+
62+ _htmlConversionBehaviors . WaitForExpression = expression ;
63+
64+ return this ;
65+ }
66+
67+ /// <summary>
68+ /// Overrides the default User-Agent extraHeaders
69+ /// </summary>
70+ /// <param name="userAgent"></param>
71+ /// <returns></returns>
72+ /// <exception cref="InvalidOperationException"></exception>
73+ [ Obsolete ( "Deprecated in Gotenberg v8+" ) ]
74+ public HtmlConversionBehaviorBuilder SetUserAgent ( string userAgent )
75+ {
76+ if ( userAgent . IsNotSet ( ) )
77+ {
78+ throw new ArgumentException ( "userAgent cannot be null or empty" , nameof ( userAgent ) ) ;
79+ }
80+
81+ _htmlConversionBehaviors . UserAgent = userAgent ;
82+
83+ return this ;
84+ }
85+
86+ /// <summary>
87+ /// Sets extra HTTP headers that Chromium will send when loading the HTML
88+ /// </summary>
89+ /// <param name="extraHeaders"></param>
90+ /// <returns></returns>
91+ /// <exception cref="InvalidOperationException"></exception>
92+ public HtmlConversionBehaviorBuilder AddAdditionalHeaders ( JObject extraHeaders )
93+ {
94+ if ( extraHeaders == null )
95+ {
96+ throw new ArgumentNullException ( nameof ( extraHeaders ) ) ;
97+ }
98+
99+ _htmlConversionBehaviors . ExtraHeaders = extraHeaders ;
100+
101+ return this ;
102+ }
103+
104+ /// <summary>
105+ /// Adds a cookie to store in the Chromium cookie jar.
106+ /// </summary>
107+ /// <param name="cookie">The cookie to add</param>
108+ /// <returns></returns>
109+ /// <exception cref="ArgumentNullException"></exception>
110+ public HtmlConversionBehaviorBuilder AddCookie ( Cookie cookie )
111+ {
112+ if ( cookie == null )
113+ {
114+ throw new ArgumentNullException ( nameof ( cookie ) ) ;
115+ }
116+
117+ _htmlConversionBehaviors . Cookies ??= new List < Cookie > ( ) ;
118+
119+ Cookie . Validate ( cookie ) ;
120+
121+ _htmlConversionBehaviors . Cookies . Add ( cookie ) ;
122+
123+ return this ;
124+ }
125+
126+ /// <summary>
127+ /// Sets the document metadata.
128+ /// Not all metadata are writable. Consider taking a look at https://exiftool.org/TagNames/XMP.html#pdf for an
129+ /// (exhaustive?) list of available metadata.
130+ /// </summary>
131+ /// <param name="dictionary"></param>
132+ /// <returns></returns>
133+ public HtmlConversionBehaviorBuilder SetMetadata ( IDictionary < string , object > dictionary )
134+ {
135+ if ( dictionary == null )
136+ {
137+ throw new ArgumentNullException ( nameof ( dictionary ) ) ;
138+ }
139+
140+ SetMetadata ( JObject . FromObject ( dictionary ) ) ;
141+
142+ return this ;
143+ }
144+
145+ /// <summary>
146+ /// Sets the document metadata.
147+ /// Not all metadata are writable. Consider taking a look at https://exiftool.org/TagNames/XMP.html#pdf for an
148+ /// (exhaustive?) list of available metadata.
149+ /// </summary>
150+ /// <param name="metadata"></param>
151+ /// <returns></returns>
152+ public HtmlConversionBehaviorBuilder SetMetadata ( JObject metadata )
153+ {
154+ if ( metadata == null )
155+ {
156+ throw new ArgumentNullException ( nameof ( metadata ) ) ;
157+ }
158+
159+ _htmlConversionBehaviors . MetaData = metadata ;
160+
161+ return this ;
162+ }
163+
164+ /// <summary>
165+ /// Tells gotenberg to return a 409 response if there are exceptions in the Chromium console.
166+ /// </summary>
167+ /// <returns></returns>
168+ public HtmlConversionBehaviorBuilder FailOnConsoleExceptions ( )
169+ {
170+ _htmlConversionBehaviors . FailOnConsoleExceptions = true ;
171+
172+ return this ;
173+ }
174+
175+ /// <summary>
176+ /// Configures gotenberg to emulate html loading as screen. By default, it loads it as print
177+ /// </summary>
178+ /// <returns></returns>
179+ public HtmlConversionBehaviorBuilder EmulateAsScreen ( )
180+ {
181+ _htmlConversionBehaviors . EmulatedMediaType = "screen" ;
182+
183+ return this ;
184+ }
185+
186+ /// <summary>
187+ /// Gotenberg 8+ ONLY: Configures gotenberg to not wait for Chromium network to be idle.
188+ /// </summary>
189+ /// <returns></returns>
190+ public HtmlConversionBehaviorBuilder SkipNetworkIdleEvent ( )
191+ {
192+ _htmlConversionBehaviors . SkipNetworkIdleEvent = true ;
193+
194+ return this ;
195+ }
196+
197+ /// <summary>
198+ /// Sets the format of the resulting PDF document
199+ /// </summary>
200+ /// <param name="format"></param>
201+ /// <returns></returns>
202+ /// <exception cref="InvalidOperationException"></exception>
203+ public HtmlConversionBehaviorBuilder SetPdfFormat ( ConversionPdfFormats format )
204+ {
205+ if ( format == default )
206+ {
207+ throw new ArgumentOutOfRangeException ( nameof ( format ) , "Invalid PDF format specified" ) ;
208+ }
209+
210+ _htmlConversionBehaviors . PdfFormat = format ;
211+
212+ return this ;
213+ }
214+
215+ /// <summary>
216+ /// This tells gotenberg to enable Universal Access for the resulting PDF.
217+ /// </summary>
218+ public HtmlConversionBehaviorBuilder SetPdfUa ( bool enablePdfUa = true )
219+ {
220+ _htmlConversionBehaviors . EnablePdfUa = enablePdfUa ;
221+
222+ return this ;
223+ }
224+ }
0 commit comments