servo_config/
prefs.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::env::consts::ARCH;
6use std::sync::{RwLock, RwLockReadGuard};
7
8use serde::{Deserialize, Serialize};
9use servo_config_macro::ServoPreferences;
10
11pub use crate::pref_util::PrefValue;
12
13static PREFERENCES: RwLock<Preferences> = RwLock::new(Preferences::const_default());
14
15pub trait PreferencesObserver: Send + Sync {
16    fn prefs_changed(&self, _changes: &[(&'static str, PrefValue)]) {}
17}
18
19static OBSERVERS: RwLock<Vec<Box<dyn PreferencesObserver>>> = RwLock::new(Vec::new());
20
21#[inline]
22/// Get the current set of global preferences for Servo.
23pub fn get() -> RwLockReadGuard<'static, Preferences> {
24    PREFERENCES.read().unwrap()
25}
26
27pub fn add_observer(observer: Box<dyn PreferencesObserver>) {
28    OBSERVERS.write().unwrap().push(observer);
29}
30
31pub fn set(preferences: Preferences) {
32    // Map between Stylo preference names and Servo preference names as the This should be
33    // kept in sync with components/script/dom/bindings/codegen/run.py which generates the
34    // DOM CSS style accessors.
35    stylo_static_prefs::set_bool("layout.unimplemented", preferences.layout_unimplemented);
36    stylo_static_prefs::set_i32("layout.threads", preferences.layout_threads as i32);
37    stylo_static_prefs::set_bool("layout.flexbox.enabled", preferences.layout_flexbox_enabled);
38    stylo_static_prefs::set_bool("layout.columns.enabled", preferences.layout_columns_enabled);
39    stylo_static_prefs::set_bool("layout.grid.enabled", preferences.layout_grid_enabled);
40    stylo_static_prefs::set_bool(
41        "layout.css.attr.enabled",
42        preferences.layout_css_attr_enabled,
43    );
44    stylo_static_prefs::set_bool(
45        "layout.css.transition-behavior.enabled",
46        preferences.layout_css_transition_behavior_enabled,
47    );
48    stylo_static_prefs::set_bool(
49        "layout.writing-mode.enabled",
50        preferences.layout_writing_mode_enabled,
51    );
52    stylo_static_prefs::set_bool(
53        "layout.container-queries.enabled",
54        preferences.layout_container_queries_enabled,
55    );
56    stylo_static_prefs::set_bool(
57        "layout.variable_fonts.enabled",
58        preferences.layout_variable_fonts_enabled,
59    );
60
61    let changed = preferences.diff(&PREFERENCES.read().unwrap());
62
63    *PREFERENCES.write().unwrap() = preferences;
64
65    for observer in &*OBSERVERS.read().unwrap() {
66        observer.prefs_changed(&changed);
67    }
68}
69
70/// A convenience macro for accessing a preference value using its static path.
71/// Passing an invalid path is a compile-time error.
72#[macro_export]
73macro_rules! pref {
74    ($name: ident) => {
75        $crate::prefs::get().$name.clone()
76    };
77}
78
79#[derive(Clone, Deserialize, Serialize, ServoPreferences)]
80pub struct Preferences {
81    pub fonts_default: String,
82    pub fonts_serif: String,
83    pub fonts_sans_serif: String,
84    pub fonts_monospace: String,
85    pub fonts_default_size: i64,
86    pub fonts_default_monospace_size: i64,
87    pub css_animations_testing_enabled: bool,
88    /// Start the devtools server at startup
89    pub devtools_server_enabled: bool,
90    /// The address +port the devtools server listens to, default to 127.0.0.1:7000.
91    pub devtools_server_listen_address: String,
92    // feature: WebGPU | #24706 | Web/API/WebGPU_API
93    pub dom_webgpu_enabled: bool,
94    /// List of comma-separated backends to be used by wgpu.
95    pub dom_webgpu_wgpu_backend: String,
96    // feature: AbortController | #34866 | Web/API/AbortController
97    pub dom_abort_controller_enabled: bool,
98    // feature: Adopted Stylesheet | #38132 | Web/API/Document/adoptedStyleSheets
99    pub dom_adoptedstylesheet_enabled: bool,
100    // feature: Clipboard API | #36084 | Web/API/Clipboard_API
101    pub dom_async_clipboard_enabled: bool,
102    pub dom_bluetooth_enabled: bool,
103    pub dom_bluetooth_testing_enabled: bool,
104    pub dom_allow_scripts_to_close_windows: bool,
105    // feature: Media Capture and Streams API | #26861 | Web/API/Media_Capture_and_Streams_API
106    pub dom_canvas_capture_enabled: bool,
107    pub dom_canvas_text_enabled: bool,
108    /// Selects canvas backend
109    ///
110    /// Available values:
111    /// - ` `/`auto`
112    /// - vello
113    /// - vello_cpu
114    pub dom_canvas_backend: String,
115    pub dom_clipboardevent_enabled: bool,
116    pub dom_command_invokers_enabled: bool,
117    pub dom_composition_event_enabled: bool,
118    // feature: CookieStore | #37674 | Web/API/CookieStore
119    pub dom_cookiestore_enabled: bool,
120    // feature: Credential Management API | #38788 | Web/API/Credential_Management_API
121    pub dom_credential_management_enabled: bool,
122    // feature: WebCrypto API | #40687 | Web/API/Web_Crypto_API
123    pub dom_crypto_subtle_enabled: bool,
124    pub dom_document_dblclick_timeout: i64,
125    pub dom_document_dblclick_dist: i64,
126    // feature: Document.execCommand | #25005 | Web/API/Document/execCommand
127    pub dom_exec_command_enabled: bool,
128    // feature: CSS Font Loading API | #29376 | Web/API/CSS_Font_Loading_API
129    pub dom_fontface_enabled: bool,
130    pub dom_fullscreen_test: bool,
131    // feature: Gamepad API | #10977 | Web/API/Gamepad_API
132    pub dom_gamepad_enabled: bool,
133    // feature: Geolocation API | #38903 | Web/API/Geolocation_API
134    pub dom_geolocation_enabled: bool,
135    // feature: IndexedDB | #6963 | Web/API/IndexedDB_API
136    pub dom_indexeddb_enabled: bool,
137    // feature: IntersectionObserver | #35767 | Web/API/Intersection_Observer_API
138    pub dom_intersection_observer_enabled: bool,
139    pub dom_microdata_testing_enabled: bool,
140    pub dom_uievent_which_enabled: bool,
141    // feature: MutationObserver | #6633 | Web/API/MutationObserver
142    pub dom_mutation_observer_enabled: bool,
143    // feature: Navigator.registerProtocolHandler() | #40615 | Web/API/Navigator/registerProtocolHandler
144    pub dom_navigator_protocol_handlers_enabled: bool,
145    // feature: Notification API | #34841 | Web/API/Notifications_API
146    pub dom_notification_enabled: bool,
147    // feature: OffscreenCanvas | #34111 | Web/API/OffscreenCanvas
148    pub dom_offscreen_canvas_enabled: bool,
149    pub dom_parallel_css_parsing_enabled: bool,
150    // feature: Permissions API | #31235 | Web/API/Permissions_API
151    pub dom_permissions_enabled: bool,
152    pub dom_permissions_testing_allowed_in_nonsecure_contexts: bool,
153    // feature: ResizeObserver | #39790 | Web/API/ResizeObserver
154    pub dom_resize_observer_enabled: bool,
155    pub dom_script_asynch: bool,
156    // feature: ServiceWorker | #36538 | Web/API/Service_Worker_API
157    pub dom_serviceworker_enabled: bool,
158    pub dom_serviceworker_timeout_seconds: i64,
159    pub dom_servo_helpers_enabled: bool,
160    pub dom_servoparser_async_html_tokenizer_enabled: bool,
161    pub dom_testbinding_enabled: bool,
162    pub dom_testbinding_prefcontrolled_enabled: bool,
163    pub dom_testbinding_prefcontrolled2_enabled: bool,
164    pub dom_testbinding_preference_value_falsy: bool,
165    pub dom_testbinding_preference_value_quote_string_test: String,
166    pub dom_testbinding_preference_value_space_string_test: String,
167    pub dom_testbinding_preference_value_string_empty: String,
168    pub dom_testbinding_preference_value_string_test: String,
169    pub dom_testbinding_preference_value_truthy: bool,
170    pub dom_testing_element_activation_enabled: bool,
171    pub dom_testing_html_input_element_select_files_enabled: bool,
172    pub dom_testperf_enabled: bool,
173    // https://testutils.spec.whatwg.org#availability
174    pub dom_testutils_enabled: bool,
175    /// <https://html.spec.whatwg.org/multipage/#transient-activation-duration>
176    pub dom_transient_activation_duration_ms: i64,
177    /// Enable WebGL2 APIs.
178    // feature: WebGL2 | #41394 | Web/API/WebGL2RenderingContext
179    pub dom_webgl2_enabled: bool,
180    // feature: WebRTC | #41396 | Web/API/WebRTC_API
181    pub dom_webrtc_enabled: bool,
182    // feature: WebRTC Transceiver | #41396 | Web/API/RTCRtpTransceiver
183    pub dom_webrtc_transceiver_enabled: bool,
184    // feature: WebVTT | #22312 | Web/API/WebVTT_API
185    pub dom_webvtt_enabled: bool,
186    pub dom_webxr_enabled: bool,
187    pub dom_webxr_test: bool,
188    pub dom_webxr_first_person_observer_view: bool,
189    pub dom_webxr_glwindow_enabled: bool,
190    pub dom_webxr_glwindow_left_right: bool,
191    pub dom_webxr_glwindow_red_cyan: bool,
192    pub dom_webxr_glwindow_spherical: bool,
193    pub dom_webxr_glwindow_cubemap: bool,
194    pub dom_webxr_hands_enabled: bool,
195    // feature: WebXR Layers | #27468 | Web/API/XRCompositionLayer
196    pub dom_webxr_layers_enabled: bool,
197    pub dom_webxr_openxr_enabled: bool,
198    pub dom_webxr_sessionavailable: bool,
199    pub dom_webxr_unsafe_assume_user_intent: bool,
200    pub dom_worklet_enabled: bool,
201    pub dom_worklet_blockingsleep: bool,
202    pub dom_worklet_testing_enabled: bool,
203    pub dom_worklet_timeout_ms: i64,
204    /// <https://drafts.csswg.org/cssom-view/#the-visualviewport-interface>
205    // feature: VisualViewport | #41341 | Web/API/VisualViewport
206    pub dom_visual_viewport_enabled: bool,
207    /// True to compile all WebRender shaders when Servo initializes. This is mostly
208    /// useful when modifying the shaders, to ensure they all compile after each change is
209    /// made.
210    pub gfx_precache_shaders: bool,
211    /// Whether or not antialiasing is enabled for text rendering.
212    pub gfx_text_antialiasing_enabled: bool,
213    /// Whether or not subpixel antialiasing is enabled for text rendering.
214    pub gfx_subpixel_text_antialiasing_enabled: bool,
215    pub gfx_texture_swizzling_enabled: bool,
216    /// The amount of image keys we request per batch for the image cache.
217    pub image_key_batch_size: i64,
218    /// Whether or not the DOM inspector should show shadow roots of user-agent shadow trees
219    pub inspector_show_servo_internal_shadow_roots: bool,
220    pub js_asmjs_enabled: bool,
221    pub js_asyncstack: bool,
222    pub js_baseline_interpreter_enabled: bool,
223    /// Whether to disable the jit within SpiderMonkey
224    pub js_disable_jit: bool,
225    pub js_baseline_jit_enabled: bool,
226    pub js_baseline_jit_unsafe_eager_compilation_enabled: bool,
227    pub js_discard_system_source: bool,
228    pub js_dump_stack_on_debuggee_would_run: bool,
229    pub js_ion_enabled: bool,
230    pub js_ion_offthread_compilation_enabled: bool,
231    pub js_ion_unsafe_eager_compilation_enabled: bool,
232    pub js_mem_gc_allocation_threshold_mb: i64,
233    pub js_mem_gc_allocation_threshold_factor: i64,
234    pub js_mem_gc_allocation_threshold_avoid_interrupt_factor: i64,
235    pub js_mem_gc_compacting_enabled: bool,
236    pub js_mem_gc_decommit_threshold_mb: i64,
237    pub js_mem_gc_dynamic_heap_growth_enabled: bool,
238    pub js_mem_gc_dynamic_mark_slice_enabled: bool,
239    pub js_mem_gc_empty_chunk_count_min: i64,
240    pub js_mem_gc_high_frequency_heap_growth_max: i64,
241    pub js_mem_gc_high_frequency_heap_growth_min: i64,
242    pub js_mem_gc_high_frequency_high_limit_mb: i64,
243    pub js_mem_gc_high_frequency_low_limit_mb: i64,
244    pub js_mem_gc_high_frequency_time_limit_ms: i64,
245    pub js_mem_gc_incremental_enabled: bool,
246    pub js_mem_gc_incremental_slice_ms: i64,
247    pub js_mem_gc_low_frequency_heap_growth: i64,
248    pub js_mem_gc_per_zone_enabled: bool,
249    pub js_mem_gc_zeal_frequency: i64,
250    pub js_mem_gc_zeal_level: i64,
251    pub js_mem_max: i64,
252    pub js_native_regex_enabled: bool,
253    pub js_offthread_compilation_enabled: bool,
254    pub js_shared_memory: bool,
255    pub js_throw_on_asmjs_validation_failure: bool,
256    pub js_throw_on_debuggee_would_run: bool,
257    pub js_timers_minimum_duration: i64,
258    pub js_wasm_baseline_enabled: bool,
259    pub js_wasm_enabled: bool,
260    pub js_wasm_ion_enabled: bool,
261    pub js_werror_enabled: bool,
262    // feature: Largest Contentful Paint | #42000 | Web/API/LargestContentfulPaint
263    pub largest_contentful_paint_enabled: bool,
264    pub layout_animations_test_enabled: bool,
265    // feature: CSS Multicol | #22397 | Web/CSS/Guides/Multicol_layout
266    pub layout_columns_enabled: bool,
267    // feature: CSS Grid | #34479 | Web/CSS/Guides/Grid_layout
268    pub layout_grid_enabled: bool,
269    pub layout_container_queries_enabled: bool,
270    pub layout_css_attr_enabled: bool,
271    pub layout_css_transition_behavior_enabled: bool,
272    // feature: CSS Flexbox | #12453 | Web/CSS/Guides/Flexible_box_layout
273    pub layout_flexbox_enabled: bool,
274    pub layout_style_sharing_cache_enabled: bool,
275    pub layout_threads: i64,
276    pub layout_unimplemented: bool,
277    // feature: Variable fonts | #38800 | Web/CSS/Guides/Fonts/Variable_fonts
278    pub layout_variable_fonts_enabled: bool,
279    // feature: CSS writing modes | #2560 | Web/CSS/Guides/Writing_modes
280    pub layout_writing_mode_enabled: bool,
281    /// Enable hardware acceleration for video playback.
282    pub media_glvideo_enabled: bool,
283    /// Enable a non-standard event handler for verifying behavior of media elements during tests.
284    pub media_testing_enabled: bool,
285    /// The default timeout set for establishing a network connection in seconds. This amount
286    /// if for the entire process of connecting to an address. For instance, if a particular host is
287    /// associated with multiple IP addresses, this timeout will be divided equally among
288    /// each IP address.
289    pub network_connection_timeout: u64,
290    pub network_enforce_tls_enabled: bool,
291    pub network_enforce_tls_localhost: bool,
292    pub network_enforce_tls_onion: bool,
293    pub network_http_cache_disabled: bool,
294    /// A url for a http proxy. We treat an empty string as no proxy.
295    pub network_http_proxy_uri: String,
296    /// A url for a https proxy. We treat an empty string as no proxy.
297    pub network_https_proxy_uri: String,
298    /// The domains for which we will not have a proxy. No effect if `network_http_proxy_uri` is not set.
299    /// The exact behavior is given by
300    /// <https://docs.rs/hyper-util/latest/hyper_util/client/proxy/matcher/struct.Builder.html#method.no>
301    pub network_http_no_proxy: String,
302    /// The weight of the http memory cache
303    /// Notice that this is not equal to the number of different urls in the cache.
304    pub network_http_cache_size: u64,
305    pub network_local_directory_listing_enabled: bool,
306    pub network_mime_sniff: bool,
307    /// Force the use of `rust-webpki` verification for CA roots. If this is false (the
308    /// default), then `rustls-platform-verifier` will be used, except on Android where
309    /// `rust-webpki` is always used.
310    pub network_use_webpki_roots: bool,
311    /// The length of the session history, in navigations, for each `WebView. Back-forward
312    /// cache entries that are more than `session_history_max_length` steps in the future or
313    /// `session_history_max_length` steps in the past will be discarded. Navigating forward
314    /// or backward to that entry will cause the entire page to be reloaded.
315    pub session_history_max_length: i64,
316    /// The background color of shell's viewport. This will be used by OpenGL's `glClearColor`.
317    pub shell_background_color_rgba: [f64; 4],
318    pub webgl_testing_context_creation_error: bool,
319    /// Number of workers per threadpool, if we fail to detect how much
320    /// parallelism is available at runtime.
321    pub threadpools_fallback_worker_num: i64,
322    /// Maximum number of workers for the Image Cache thread pool
323    pub threadpools_image_cache_workers_max: i64,
324    /// Maximum number of workers for the IndexedDB thread pool
325    pub threadpools_indexeddb_workers_max: i64,
326    /// Maximum number of workers for the Web Storage thread pool
327    pub threadpools_webstorage_workers_max: i64,
328    /// Maximum number of workers for the Networking async runtime thread pool
329    pub threadpools_async_runtime_workers_max: i64,
330    /// Maximum number of workers for webrender
331    pub threadpools_webrender_workers_max: i64,
332    /// The user-agent to use for Servo. This can also be set via [`UserAgentPlatform`] in
333    /// order to set the value to the default value for the given platform.
334    pub user_agent: String,
335    /// Whether or not the viewport meta tag is enabled.
336    pub viewport_meta_enabled: bool,
337    pub log_filter: String,
338    /// Whether the accessibility code is enabled.
339    pub accessibility_enabled: bool,
340}
341
342impl Preferences {
343    const fn const_default() -> Self {
344        Self {
345            css_animations_testing_enabled: false,
346            devtools_server_enabled: false,
347            devtools_server_listen_address: String::new(),
348            dom_abort_controller_enabled: true,
349            dom_adoptedstylesheet_enabled: false,
350            dom_allow_scripts_to_close_windows: false,
351            dom_async_clipboard_enabled: false,
352            dom_bluetooth_enabled: false,
353            dom_bluetooth_testing_enabled: false,
354            dom_canvas_capture_enabled: false,
355            dom_canvas_text_enabled: true,
356            dom_canvas_backend: String::new(),
357            dom_clipboardevent_enabled: true,
358            dom_command_invokers_enabled: false,
359            dom_composition_event_enabled: false,
360            dom_cookiestore_enabled: false,
361            dom_credential_management_enabled: false,
362            dom_crypto_subtle_enabled: true,
363            dom_document_dblclick_dist: 1,
364            dom_document_dblclick_timeout: 300,
365            dom_exec_command_enabled: false,
366            dom_fontface_enabled: false,
367            dom_fullscreen_test: false,
368            dom_gamepad_enabled: true,
369            dom_geolocation_enabled: false,
370            dom_indexeddb_enabled: false,
371            dom_intersection_observer_enabled: false,
372            dom_microdata_testing_enabled: false,
373            dom_uievent_which_enabled: true,
374            dom_mutation_observer_enabled: true,
375            dom_navigator_protocol_handlers_enabled: false,
376            dom_notification_enabled: false,
377            dom_parallel_css_parsing_enabled: true,
378            dom_offscreen_canvas_enabled: false,
379            dom_permissions_enabled: false,
380            dom_permissions_testing_allowed_in_nonsecure_contexts: false,
381            dom_resize_observer_enabled: true,
382            dom_script_asynch: true,
383            dom_serviceworker_enabled: false,
384            dom_serviceworker_timeout_seconds: 60,
385            dom_servo_helpers_enabled: false,
386            dom_servoparser_async_html_tokenizer_enabled: false,
387            dom_testbinding_enabled: false,
388            dom_testbinding_prefcontrolled2_enabled: false,
389            dom_testbinding_prefcontrolled_enabled: false,
390            dom_testbinding_preference_value_falsy: false,
391            dom_testbinding_preference_value_quote_string_test: String::new(),
392            dom_testbinding_preference_value_space_string_test: String::new(),
393            dom_testbinding_preference_value_string_empty: String::new(),
394            dom_testbinding_preference_value_string_test: String::new(),
395            dom_testbinding_preference_value_truthy: false,
396            dom_testing_element_activation_enabled: false,
397            dom_testing_html_input_element_select_files_enabled: false,
398            dom_testperf_enabled: false,
399            dom_testutils_enabled: false,
400            dom_transient_activation_duration_ms: 5000,
401            dom_webgl2_enabled: false,
402            dom_webgpu_enabled: false,
403            dom_webgpu_wgpu_backend: String::new(),
404            dom_webrtc_enabled: false,
405            dom_webrtc_transceiver_enabled: false,
406            dom_webvtt_enabled: false,
407            dom_webxr_enabled: true,
408            dom_webxr_first_person_observer_view: false,
409            dom_webxr_glwindow_cubemap: false,
410            dom_webxr_glwindow_enabled: true,
411            dom_webxr_glwindow_left_right: false,
412            dom_webxr_glwindow_red_cyan: false,
413            dom_webxr_glwindow_spherical: false,
414            dom_webxr_hands_enabled: true,
415            dom_webxr_layers_enabled: false,
416            dom_webxr_openxr_enabled: true,
417            dom_webxr_sessionavailable: false,
418            dom_webxr_test: false,
419            dom_webxr_unsafe_assume_user_intent: false,
420            dom_worklet_blockingsleep: false,
421            dom_worklet_enabled: false,
422            dom_worklet_testing_enabled: false,
423            dom_worklet_timeout_ms: 10,
424            dom_visual_viewport_enabled: false,
425            accessibility_enabled: false,
426            fonts_default: String::new(),
427            fonts_default_monospace_size: 13,
428            fonts_default_size: 16,
429            fonts_monospace: String::new(),
430            fonts_sans_serif: String::new(),
431            fonts_serif: String::new(),
432            gfx_precache_shaders: false,
433            gfx_text_antialiasing_enabled: true,
434            gfx_subpixel_text_antialiasing_enabled: true,
435            gfx_texture_swizzling_enabled: true,
436            image_key_batch_size: 10,
437            inspector_show_servo_internal_shadow_roots: false,
438            js_asmjs_enabled: true,
439            js_asyncstack: false,
440            js_baseline_interpreter_enabled: true,
441            js_baseline_jit_enabled: true,
442            js_baseline_jit_unsafe_eager_compilation_enabled: false,
443            js_disable_jit: false,
444            js_discard_system_source: false,
445            js_dump_stack_on_debuggee_would_run: false,
446            js_ion_enabled: true,
447            js_ion_offthread_compilation_enabled: true,
448            js_ion_unsafe_eager_compilation_enabled: false,
449            js_mem_gc_allocation_threshold_avoid_interrupt_factor: 100,
450            js_mem_gc_allocation_threshold_factor: 100,
451            js_mem_gc_allocation_threshold_mb: 30,
452            js_mem_gc_compacting_enabled: true,
453            js_mem_gc_decommit_threshold_mb: 32,
454            js_mem_gc_dynamic_heap_growth_enabled: true,
455            js_mem_gc_dynamic_mark_slice_enabled: true,
456            js_mem_gc_empty_chunk_count_min: 1,
457            js_mem_gc_high_frequency_heap_growth_max: 300,
458            js_mem_gc_high_frequency_heap_growth_min: 150,
459            js_mem_gc_high_frequency_high_limit_mb: 500,
460            js_mem_gc_high_frequency_low_limit_mb: 100,
461            js_mem_gc_high_frequency_time_limit_ms: 1000,
462            js_mem_gc_incremental_enabled: true,
463            js_mem_gc_incremental_slice_ms: 10,
464            js_mem_gc_low_frequency_heap_growth: 150,
465            js_mem_gc_per_zone_enabled: false,
466            js_mem_gc_zeal_frequency: 100,
467            js_mem_gc_zeal_level: 0,
468            js_mem_max: -1,
469            js_native_regex_enabled: true,
470            js_offthread_compilation_enabled: true,
471            js_shared_memory: true,
472            js_throw_on_asmjs_validation_failure: false,
473            js_throw_on_debuggee_would_run: false,
474            js_timers_minimum_duration: 1000,
475            js_wasm_baseline_enabled: true,
476            js_wasm_enabled: true,
477            js_wasm_ion_enabled: true,
478            js_werror_enabled: false,
479            largest_contentful_paint_enabled: false,
480            layout_animations_test_enabled: false,
481            layout_columns_enabled: false,
482            layout_container_queries_enabled: false,
483            layout_css_attr_enabled: false,
484            layout_css_transition_behavior_enabled: true,
485            layout_flexbox_enabled: true,
486            layout_grid_enabled: false,
487            layout_style_sharing_cache_enabled: true,
488            // TODO(mrobinson): This should likely be based on the number of processors.
489            layout_threads: 3,
490            layout_unimplemented: false,
491            layout_variable_fonts_enabled: false,
492            layout_writing_mode_enabled: false,
493            media_glvideo_enabled: false,
494            media_testing_enabled: false,
495            network_connection_timeout: 15,
496            network_enforce_tls_enabled: false,
497            network_enforce_tls_localhost: false,
498            network_enforce_tls_onion: false,
499            network_http_cache_disabled: false,
500            network_http_proxy_uri: String::new(),
501            network_https_proxy_uri: String::new(),
502            network_http_no_proxy: String::new(),
503            network_http_cache_size: 5000,
504            network_local_directory_listing_enabled: true,
505            network_mime_sniff: false,
506            network_use_webpki_roots: false,
507            session_history_max_length: 20,
508            shell_background_color_rgba: [1.0, 1.0, 1.0, 1.0],
509            threadpools_async_runtime_workers_max: 6,
510            threadpools_fallback_worker_num: 3,
511            threadpools_image_cache_workers_max: 4,
512            threadpools_indexeddb_workers_max: 4,
513            threadpools_webstorage_workers_max: 4,
514            threadpools_webrender_workers_max: 4,
515            webgl_testing_context_creation_error: false,
516            user_agent: String::new(),
517            viewport_meta_enabled: false,
518            log_filter: String::new(),
519        }
520    }
521}
522
523impl Default for Preferences {
524    fn default() -> Self {
525        let mut preferences = Self::const_default();
526        preferences.user_agent = UserAgentPlatform::default().to_user_agent_string();
527        if let Ok(proxy_uri) = std::env::var("http_proxy").or_else(|_| std::env::var("HTTP_PROXY"))
528        {
529            preferences.network_http_proxy_uri = proxy_uri;
530        }
531        if let Ok(proxy_uri) =
532            std::env::var("https_proxy").or_else(|_| std::env::var("HTTPS_PROXY"))
533        {
534            preferences.network_https_proxy_uri = proxy_uri;
535        }
536        if let Ok(no_proxy) = std::env::var("no_proxy").or_else(|_| std::env::var("NO_PROXY")) {
537            preferences.network_http_no_proxy = no_proxy
538        }
539
540        preferences
541    }
542}
543
544pub enum UserAgentPlatform {
545    Desktop,
546    Android,
547    OpenHarmony,
548    Ios,
549}
550
551impl UserAgentPlatform {
552    /// Return the default `UserAgentPlatform` for this platform. This is
553    /// not an implementation of `Default` so that it can be `const`.
554    pub const fn default() -> Self {
555        if cfg!(target_os = "android") {
556            Self::Android
557        } else if cfg!(target_env = "ohos") {
558            Self::OpenHarmony
559        } else if cfg!(target_os = "ios") {
560            Self::Ios
561        } else {
562            Self::Desktop
563        }
564    }
565}
566
567impl UserAgentPlatform {
568    /// Convert this [`UserAgentPlatform`] into its corresponding `String` value, ie the
569    /// default user-agent to use for this platform.
570    pub fn to_user_agent_string(&self) -> String {
571        const SERVO_VERSION: &str = env!("CARGO_PKG_VERSION");
572        match self {
573            UserAgentPlatform::Desktop
574                if cfg!(all(target_os = "windows", target_arch = "x86_64")) =>
575            {
576                format!(
577                    "Mozilla/5.0 (Windows NT 10.0; Win64; {ARCH}rv:140.0) Servo/{SERVO_VERSION} Firefox/140.0"
578                )
579            },
580            UserAgentPlatform::Desktop if cfg!(target_os = "macos") => {
581                format!(
582                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:140.0) Servo/{SERVO_VERSION} Firefox/140.0"
583                )
584            },
585            UserAgentPlatform::Desktop => {
586                format!(
587                    "Mozilla/5.0 (X11; Linux {ARCH}; rv:140.0) Servo/{SERVO_VERSION} Firefox/140.0"
588                )
589            },
590            UserAgentPlatform::Android => {
591                format!(
592                    "Mozilla/5.0 (Android 10; Mobile; rv:140.0) Servo/{SERVO_VERSION} Firefox/140.0"
593                )
594            },
595            UserAgentPlatform::OpenHarmony => format!(
596                "Mozilla/5.0 (OpenHarmony; Mobile; rv:140.0) Servo/{SERVO_VERSION} Firefox/140.0"
597            ),
598            UserAgentPlatform::Ios => format!(
599                "Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X; rv:140.0) Servo/{SERVO_VERSION} Firefox/140.0"
600            ),
601        }
602    }
603}