diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 8007506c8de..523b52fd95a 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -12,6 +12,7 @@ use std::f64::consts::PI; use std::mem; use std::rc::Rc; use std::slice::from_ref; +use std::str::FromStr; use std::sync::{LazyLock, Mutex}; use std::time::{Duration, Instant}; @@ -20,7 +21,9 @@ use base::id::WebViewId; use canvas_traits::canvas::CanvasId; use canvas_traits::webgl::{self, WebGLContextId, WebGLMsg}; use chrono::Local; -use constellation_traits::{AnimationTickType, ScriptToConstellationMessage}; +use constellation_traits::{ + AnimationTickType, NavigationHistoryBehavior, ScriptToConstellationMessage, +}; use content_security_policy::{self as csp, CspList, PolicyDisposition}; use cookie::Cookie; use cssparser::match_ignore_ascii_case; @@ -51,6 +54,7 @@ use num_traits::ToPrimitive; use percent_encoding::percent_decode; use profile_traits::ipc as profile_ipc; use profile_traits::time::TimerMetadataFrameType; +use regex::bytes::Regex; use script_bindings::interfaces::DocumentHelpers; use script_layout_interface::{PendingRestyle, TrustedNodeAddress}; use script_traits::{ConstellationInputEvent, DocumentActivity, ProgressiveWebMetricType}; @@ -151,13 +155,12 @@ use crate::dom::htmlhtmlelement::HTMLHtmlElement; use crate::dom::htmliframeelement::HTMLIFrameElement; use crate::dom::htmlimageelement::HTMLImageElement; use crate::dom::htmlinputelement::HTMLInputElement; -use crate::dom::htmlmetaelement::RefreshRedirectDue; use crate::dom::htmlscriptelement::{HTMLScriptElement, ScriptResult}; use crate::dom::htmltextareaelement::HTMLTextAreaElement; use crate::dom::htmltitleelement::HTMLTitleElement; use crate::dom::intersectionobserver::IntersectionObserver; use crate::dom::keyboardevent::KeyboardEvent; -use crate::dom::location::Location; +use crate::dom::location::{Location, NavigationType}; use crate::dom::messageevent::MessageEvent; use crate::dom::mouseevent::MouseEvent; use crate::dom::node::{ @@ -242,6 +245,24 @@ impl FireMouseEventType { } } +#[derive(JSTraceable, MallocSizeOf)] +pub(crate) struct RefreshRedirectDue { + #[no_trace] + pub(crate) url: ServoUrl, + #[ignore_malloc_size_of = "non-owning"] + pub(crate) window: DomRoot, +} +impl RefreshRedirectDue { + pub(crate) fn invoke(self, can_gc: CanGc) { + self.window.Location().navigate( + self.url.clone(), + NavigationHistoryBehavior::Replace, + NavigationType::DeclarativeRefresh, + can_gc, + ); + } +} + #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)] pub(crate) enum IsHTMLDocument { HTMLDocument, @@ -4743,6 +4764,93 @@ impl Document { self.image_animation_manager.borrow_mut() } + /// + pub(crate) fn shared_declarative_refresh_steps(&self, content: &[u8]) { + // 1. If document's will declaratively refresh is true, then return. + if self.will_declaratively_refresh() { + return; + } + + // 2-11 Parsing + static REFRESH_REGEX: LazyLock = LazyLock::new(|| { + // s flag is used to match . on newlines since the only places we use . in the + // regex is to go "to end of the string" + // (?s-u:.) is used to consume invalid unicode bytes + Regex::new( + r#"(?xs) + ^ + \s* # 3 + ((?