/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::borrow::{Cow, ToOwned}; use std::cell::{Cell, RefCell, RefMut}; use std::cmp; use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::default::Default; use std::io::{stderr, stdout, Write}; use std::ptr::NonNull; use std::rc::Rc; use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use app_units::Au; use backtrace::Backtrace; use base::cross_process_instant::CrossProcessInstant; use base::id::{BrowsingContextId, PipelineId}; use base64::Engine; use bluetooth_traits::BluetoothRequest; use canvas_traits::webgl::WebGLChan; use crossbeam_channel::{unbounded, Sender}; use cssparser::{Parser, ParserInput, SourceLocation}; use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType}; use dom_struct::dom_struct; use embedder_traits::{EmbedderMsg, PromptDefinition, PromptOrigin, PromptResult}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect}; use euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::conversions::ToJSValConvertible; use js::jsapi::{GCReason, Heap, JSAutoRealm, JSObject, StackFormat, JSPROP_ENUMERATE, JS_GC}; use js::jsval::{NullValue, UndefinedValue}; use js::rust::wrappers::JS_DefineProperty; use js::rust::{ CustomAutoRooter, CustomAutoRooterGuard, HandleObject, HandleValue, MutableHandleObject, MutableHandleValue, }; use malloc_size_of::MallocSizeOf; use media::WindowGLContext; use net_traits::image_cache::{ ImageCache, ImageResponder, ImageResponse, PendingImageId, PendingImageResponse, }; use net_traits::storage_thread::StorageType; use net_traits::ResourceThreads; use num_traits::ToPrimitive; use profile_traits::ipc as ProfiledIpc; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; use script_layout_interface::{ combine_id_with_fragment_type, FragmentType, IFrameSizes, Layout, PendingImageState, QueryMsg, Reflow, ReflowGoal, ReflowRequest, TrustedNodeAddress, }; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use script_traits::{ ConstellationControlMsg, DocumentState, HistoryEntryReplacement, IFrameSizeMsg, LoadData, ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, Theme, TimerSchedulerMsg, WindowSizeData, WindowSizeType, }; use selectors::attr::CaseSensitivity; use servo_arc::Arc as ServoArc; use servo_atoms::Atom; use servo_config::pref; use servo_geometry::{f32_rect_to_au_rect, DeviceIndependentIntRect, MaxRect}; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use style::dom::OpaqueNode; use style::error_reporting::{ContextualParseError, ParseErrorReporter}; use style::media_queries; use style::parser::ParserContext as CssParserContext; use style::properties::style_structs::Font; use style::properties::PropertyId; use style::queries::values::PrefersColorScheme; use style::selector_parser::PseudoElement; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::{CssRuleType, Origin, UrlExtraData}; use style_traits::{CSSPixel, ParsingMode}; use url::Position; use webrender_api::units::{DevicePixel, LayoutPixel}; use webrender_api::{DocumentId, ExternalScrollId}; use webrender_traits::CrossProcessCompositorApi; use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions; use super::bindings::trace::HashMapTracedValues; use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::DocumentBinding::{ DocumentMethods, DocumentReadyState, }; use crate::dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use crate::dom::bindings::codegen::Bindings::HistoryBinding::History_Binding::HistoryMethods; use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{ ImageBitmapOptions, ImageBitmapSource, }; use crate::dom::bindings::codegen::Bindings::MediaQueryListBinding::MediaQueryList_Binding::MediaQueryListMethods; use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit; use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction; use crate::dom::bindings::codegen::Bindings::WindowBinding::{ self, FrameRequestCallback, ScrollBehavior, ScrollToOptions, WindowMethods, WindowPostMessageOptions, }; use crate::dom::bindings::codegen::UnionTypes::{RequestOrUSVString, StringOrFunction}; use crate::dom::bindings::error::{Error, ErrorResult, Fallible}; use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; use crate::dom::bindings::num::Finite; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::bindings::structuredclone; use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox}; use crate::dom::bindings::utils::GlobalStaticData; use crate::dom::bindings::weakref::DOMTracker; use crate::dom::bluetooth::BluetoothExtraPermissionData; use crate::dom::crypto::Crypto; use crate::dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner}; use crate::dom::customelementregistry::CustomElementRegistry; use crate::dom::document::{AnimationFrameCallback, Document, ReflowTriggerCondition}; use crate::dom::element::Element; use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::hashchangeevent::HashChangeEvent; use crate::dom::history::History; use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection}; use crate::dom::htmliframeelement::HTMLIFrameElement; use crate::dom::location::Location; use crate::dom::mediaquerylist::{MediaQueryList, MediaQueryListMatchState}; use crate::dom::mediaquerylistevent::MediaQueryListEvent; use crate::dom::messageevent::MessageEvent; use crate::dom::navigator::Navigator; use crate::dom::node::{document_from_node, from_untrusted_node_address, Node, NodeDamage}; use crate::dom::performance::Performance; use crate::dom::promise::Promise; use crate::dom::screen::Screen; use crate::dom::selection::Selection; use crate::dom::storage::Storage; use crate::dom::testrunner::TestRunner; use crate::dom::types::UIEvent; use crate::dom::webglrenderingcontext::WebGLCommandSender; #[cfg(feature = "webgpu")] use crate::dom::webgpu::identityhub::IdentityHub; use crate::dom::windowproxy::{WindowProxy, WindowProxyHandler}; use crate::dom::worklet::Worklet; use crate::dom::workletglobalscope::WorkletGlobalScopeType; use crate::layout_image::fetch_image_for_layout; use crate::microtask::MicrotaskQueue; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::{ CanGc, CommonScriptMsg, JSContext, Runtime, ScriptChan, ScriptPort, ScriptThreadEventCategory, }; use crate::script_thread::{ with_script_thread, ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg, ScriptThread, SendableMainThreadScriptChan, }; use crate::task_manager::TaskManager; use crate::task_source::{TaskSource, TaskSourceName}; use crate::timers::{IsInterval, TimerCallback}; use crate::unminify::unminified_path; use crate::webdriver_handlers::jsval_to_webdriver; use crate::{fetch, window_named_properties}; /// Current state of the window object #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)] enum WindowState { Alive, Zombie, // Pipeline is closed, but the window hasn't been GCed yet. } /// How long we should wait before performing the initial reflow after `
` is parsed, /// assuming that `` take this long to parse. const INITIAL_REFLOW_DELAY: Duration = Duration::from_millis(200); /// During loading and parsing, layouts are suppressed to avoid flashing incomplete page /// contents. /// /// Exceptions: /// - Parsing the body takes so long, that layouts are no longer suppressed in order /// to show the user that the page is loading. /// - Script triggers a layout query or scroll event in which case, we want to layout /// but not display the contents. /// /// For more information see: