aboutsummaryrefslogtreecommitdiffstats
path: root/components/shared
diff options
context:
space:
mode:
Diffstat (limited to 'components/shared')
-rw-r--r--components/shared/base/id.rs5
-rw-r--r--components/shared/compositing/display_list.rs154
-rw-r--r--components/shared/compositing/lib.rs2
-rw-r--r--components/shared/compositing/tests/compositor.rs43
-rw-r--r--components/shared/constellation/lib.rs2
-rw-r--r--components/shared/constellation/structured_data/mod.rs4
-rw-r--r--components/shared/constellation/structured_data/serializable.rs6
-rw-r--r--components/shared/constellation/structured_data/transferable.rs10
-rw-r--r--components/shared/embedder/resources.rs4
-rw-r--r--components/shared/net/Cargo.toml1
-rw-r--r--components/shared/net/fetch/headers.rs93
-rw-r--r--components/shared/net/pub_domains.rs8
-rw-r--r--components/shared/net/response.rs10
-rw-r--r--components/shared/net/storage_thread.rs4
14 files changed, 264 insertions, 82 deletions
diff --git a/components/shared/base/id.rs b/components/shared/base/id.rs
index cc4ad947494..b6ad1b3de9b 100644
--- a/components/shared/base/id.rs
+++ b/components/shared/base/id.rs
@@ -17,7 +17,7 @@ use malloc_size_of::MallocSizeOfOps;
use malloc_size_of_derive::MallocSizeOf;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
-use webrender_api::{ExternalScrollId, PipelineId as WebRenderPipelineId, SpatialId};
+use webrender_api::{ExternalScrollId, PipelineId as WebRenderPipelineId};
/// Asserts the size of a type at compile time.
macro_rules! size_of_test {
@@ -397,7 +397,4 @@ pub const TEST_WEBVIEW_ID: WebViewId = WebViewId(TEST_BROWSING_CONTEXT_ID);
pub struct ScrollTreeNodeId {
/// The index of this scroll tree node in the tree's array of nodes.
pub index: usize,
-
- /// The WebRender spatial id of this scroll tree node.
- pub spatial_id: SpatialId,
}
diff --git a/components/shared/compositing/display_list.rs b/components/shared/compositing/display_list.rs
index 6aa822cb145..4fb0d5e94db 100644
--- a/components/shared/compositing/display_list.rs
+++ b/components/shared/compositing/display_list.rs
@@ -6,11 +6,17 @@
use base::id::ScrollTreeNodeId;
use embedder_traits::Cursor;
+use euclid::SideOffsets2D;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize};
use style::values::specified::Overflow;
-use webrender_api::units::{LayoutSize, LayoutVector2D};
-use webrender_api::{Epoch, ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
+use webrender_api::units::{
+ LayoutPixel, LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D,
+};
+use webrender_api::{
+ Epoch, ExternalScrollId, PipelineId, ReferenceFrameKind, ScrollLocation, SpatialId,
+ StickyOffsetBounds, TransformStyle,
+};
/// The scroll sensitivity of a scroll node in a particular axis ie whether it can be scrolled due to
/// input events and script events or only script events.
@@ -56,6 +62,29 @@ pub struct HitTestInfo {
pub scroll_tree_node: ScrollTreeNodeId,
}
+#[derive(Debug, Deserialize, Serialize)]
+pub enum SpatialTreeNodeInfo {
+ ReferenceFrame(ReferenceFrameNodeInfo),
+ Scroll(ScrollableNodeInfo),
+ Sticky(StickyNodeInfo),
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+pub struct StickyNodeInfo {
+ pub frame_rect: LayoutRect,
+ pub margins: SideOffsets2D<Option<f32>, LayoutPixel>,
+ pub vertical_offset_bounds: StickyOffsetBounds,
+ pub horizontal_offset_bounds: StickyOffsetBounds,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+pub struct ReferenceFrameNodeInfo {
+ pub origin: LayoutPoint,
+ pub transform_style: TransformStyle,
+ pub transform: LayoutTransform,
+ pub kind: ReferenceFrameKind,
+}
+
/// Data stored for nodes in the [ScrollTree] that actually scroll,
/// as opposed to reference frames and sticky nodes which do not.
#[derive(Debug, Deserialize, Serialize)]
@@ -64,8 +93,11 @@ pub struct ScrollableNodeInfo {
/// it between successive re-layouts.
pub external_id: ExternalScrollId,
- /// Amount that this `ScrollableNode` can scroll in both directions.
- pub scrollable_size: LayoutSize,
+ /// The content rectangle for this scroll node;
+ pub content_rect: LayoutRect,
+
+ /// The clip rectange for this scroll node.
+ pub clip_rect: LayoutRect,
/// Whether this `ScrollableNode` is sensitive to input events.
pub scroll_sensitivity: AxesScrollSensitivity,
@@ -74,6 +106,12 @@ pub struct ScrollableNodeInfo {
pub offset: LayoutVector2D,
}
+impl ScrollableNodeInfo {
+ fn scrollable_size(&self) -> LayoutSize {
+ self.content_rect.size() - self.clip_rect.size()
+ }
+}
+
#[derive(Debug, Deserialize, Serialize)]
/// A node in a tree of scroll nodes. This may either be a scrollable
/// node which responds to scroll events or a non-scrollable one.
@@ -82,35 +120,51 @@ pub struct ScrollTreeNode {
/// None then this is the root node.
pub parent: Option<ScrollTreeNodeId>,
- /// Scrolling data which will not be None if this is a scrolling node.
- pub scroll_info: Option<ScrollableNodeInfo>,
+ /// The WebRender id, which is filled in when this tree is serialiezd
+ /// into a WebRender display list.
+ pub webrender_id: Option<SpatialId>,
+
+ /// Specific information about this node, depending on whether it is a scroll node
+ /// or a reference frame.
+ pub info: SpatialTreeNodeInfo,
}
impl ScrollTreeNode {
+ /// Get the WebRender [`SpatialId`] for the given [`ScrollNodeId`]. This will
+ /// panic if [`ScrollTree::build_display_list`] has not been called yet.
+ pub fn webrender_id(&self) -> SpatialId {
+ self.webrender_id
+ .expect("Should have called ScrollTree::build_display_list before querying SpatialId")
+ }
+
/// Get the external id of this node.
pub fn external_id(&self) -> Option<ExternalScrollId> {
- self.scroll_info.as_ref().map(|info| info.external_id)
+ match self.info {
+ SpatialTreeNodeInfo::Scroll(ref info) => Some(info.external_id),
+ _ => None,
+ }
}
/// Get the offset id of this node if it applies.
pub fn offset(&self) -> Option<LayoutVector2D> {
- self.scroll_info.as_ref().map(|info| info.offset)
+ match self.info {
+ SpatialTreeNodeInfo::Scroll(ref info) => Some(info.offset),
+ _ => None,
+ }
}
/// Set the offset for this node, returns false if this was a
/// non-scrolling node for which you cannot set the offset.
pub fn set_offset(&mut self, new_offset: LayoutVector2D) -> bool {
- match self.scroll_info {
- Some(ref mut info) => {
- let scrollable_width = info.scrollable_size.width;
- let scrollable_height = info.scrollable_size.height;
-
- if scrollable_width > 0. {
- info.offset.x = (new_offset.x).min(0.0).max(-scrollable_width);
+ match self.info {
+ SpatialTreeNodeInfo::Scroll(ref mut info) => {
+ let scrollable_size = info.scrollable_size();
+ if scrollable_size.width > 0. {
+ info.offset.x = (new_offset.x).min(0.0).max(-scrollable_size.width);
}
- if scrollable_height > 0. {
- info.offset.y = (new_offset.y).min(0.0).max(-scrollable_height);
+ if scrollable_size.height > 0. {
+ info.offset.y = (new_offset.y).min(0.0).max(-scrollable_size.height);
}
true
},
@@ -125,9 +179,9 @@ impl ScrollTreeNode {
&mut self,
scroll_location: ScrollLocation,
) -> Option<(ExternalScrollId, LayoutVector2D)> {
- let info = match self.scroll_info {
- Some(ref mut data) => data,
- None => return None,
+ let info = match self.info {
+ SpatialTreeNodeInfo::Scroll(ref mut info) => info,
+ _ => return None,
};
if info.scroll_sensitivity.x != ScrollSensitivity::ScriptAndInputEvents &&
@@ -148,7 +202,7 @@ impl ScrollTreeNode {
return Some((info.external_id, info.offset));
},
ScrollLocation::End => {
- let end_pos = -info.scrollable_size.height;
+ let end_pos = -info.scrollable_size().height;
if info.offset.y.round() <= end_pos {
// Nothing to do on this layer.
return None;
@@ -159,20 +213,23 @@ impl ScrollTreeNode {
},
};
- let scrollable_width = info.scrollable_size.width;
- let scrollable_height = info.scrollable_size.height;
+ let scrollable_size = info.scrollable_size();
let original_layer_scroll_offset = info.offset;
- if scrollable_width > 0. &&
+ if scrollable_size.width > 0. &&
info.scroll_sensitivity.x == ScrollSensitivity::ScriptAndInputEvents
{
- info.offset.x = (info.offset.x + delta.x).min(0.0).max(-scrollable_width);
+ info.offset.x = (info.offset.x + delta.x)
+ .min(0.0)
+ .max(-scrollable_size.width);
}
- if scrollable_height > 0. &&
+ if scrollable_size.height > 0. &&
info.scroll_sensitivity.y == ScrollSensitivity::ScriptAndInputEvents
{
- info.offset.y = (info.offset.y + delta.y).min(0.0).max(-scrollable_height);
+ info.offset.y = (info.offset.y + delta.y)
+ .min(0.0)
+ .max(-scrollable_size.height);
}
if info.offset != original_layer_scroll_offset {
@@ -199,16 +256,23 @@ impl ScrollTree {
pub fn add_scroll_tree_node(
&mut self,
parent: Option<&ScrollTreeNodeId>,
- spatial_id: SpatialId,
- scroll_info: Option<ScrollableNodeInfo>,
+ info: SpatialTreeNodeInfo,
) -> ScrollTreeNodeId {
self.nodes.push(ScrollTreeNode {
parent: parent.cloned(),
- scroll_info,
+ webrender_id: None,
+ info,
});
ScrollTreeNodeId {
index: self.nodes.len() - 1,
- spatial_id,
+ }
+ }
+
+ /// Once WebRender display list construction is complete for this [`ScrollTree`], update
+ /// the mapping of nodes to WebRender [`SpatialId`]s.
+ pub fn update_mapping(&mut self, mapping: Vec<SpatialId>) {
+ for (spatial_id, node) in mapping.into_iter().zip(self.nodes.iter_mut()) {
+ node.webrender_id = Some(spatial_id);
}
}
@@ -218,10 +282,16 @@ impl ScrollTree {
}
/// Get an immutable reference to the node with the given index.
- pub fn get_node(&mut self, id: &ScrollTreeNodeId) -> &ScrollTreeNode {
+ pub fn get_node(&self, id: &ScrollTreeNodeId) -> &ScrollTreeNode {
&self.nodes[id.index]
}
+ /// Get the WebRender [`SpatialId`] for the given [`ScrollNodeId`]. This will
+ /// panic if [`ScrollTree::build_display_list`] has not been called yet.
+ pub fn webrender_id(&self, id: &ScrollTreeNodeId) -> SpatialId {
+ self.get_node(id).webrender_id()
+ }
+
/// Scroll the given scroll node on this scroll tree. If the node cannot be scrolled,
/// because it isn't a scrollable node or it's already scrolled to the maximum scroll
/// extent, try to scroll an ancestor of this node. Returns the node scrolled and the
@@ -251,8 +321,10 @@ impl ScrollTree {
offset: LayoutVector2D,
) -> bool {
for node in self.nodes.iter_mut() {
- match node.scroll_info {
- Some(ref mut scroll_info) if scroll_info.external_id == external_scroll_id => {
+ match node.info {
+ SpatialTreeNodeInfo::Scroll(ref mut scroll_info)
+ if scroll_info.external_id == external_scroll_id =>
+ {
scroll_info.offset = offset;
return true;
},
@@ -320,15 +392,19 @@ impl CompositorDisplayListInfo {
let mut scroll_tree = ScrollTree::default();
let root_reference_frame_id = scroll_tree.add_scroll_tree_node(
None,
- SpatialId::root_reference_frame(pipeline_id),
- None,
+ SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo {
+ origin: Default::default(),
+ transform_style: TransformStyle::Flat,
+ transform: LayoutTransform::identity(),
+ kind: ReferenceFrameKind::default(),
+ }),
);
let root_scroll_node_id = scroll_tree.add_scroll_tree_node(
Some(&root_reference_frame_id),
- SpatialId::root_scroll_node(pipeline_id),
- Some(ScrollableNodeInfo {
+ SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo {
external_id: ExternalScrollId(0, pipeline_id),
- scrollable_size: content_size - viewport_size,
+ content_rect: LayoutRect::from_origin_and_size(LayoutPoint::zero(), content_size),
+ clip_rect: LayoutRect::from_origin_and_size(LayoutPoint::zero(), viewport_size),
scroll_sensitivity: viewport_scroll_sensitivity,
offset: LayoutVector2D::zero(),
}),
diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs
index a6701ca2b52..061dfe023df 100644
--- a/components/shared/compositing/lib.rs
+++ b/components/shared/compositing/lib.rs
@@ -236,7 +236,7 @@ impl CrossProcessCompositorApi {
pub fn send_display_list(
&self,
webview_id: WebViewId,
- display_list_info: CompositorDisplayListInfo,
+ display_list_info: &CompositorDisplayListInfo,
list: BuiltDisplayList,
) {
let (display_list_data, display_list_descriptor) = list.into_data();
diff --git a/components/shared/compositing/tests/compositor.rs b/components/shared/compositing/tests/compositor.rs
index 4d2ecfd99c9..e04f1770964 100644
--- a/components/shared/compositing/tests/compositor.rs
+++ b/components/shared/compositing/tests/compositor.rs
@@ -4,11 +4,12 @@
use base::id::ScrollTreeNodeId;
use compositing_traits::display_list::{
- AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo,
+ AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo, SpatialTreeNodeInfo,
+ StickyNodeInfo,
};
-use euclid::Size2D;
+use euclid::{SideOffsets2D, Size2D};
use webrender_api::units::LayoutVector2D;
-use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
+use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, StickyOffsetBounds};
fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {
let pipeline_id = PipelineId(0, 0);
@@ -16,7 +17,6 @@ fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {
let parent = if num_nodes > 0 {
Some(ScrollTreeNodeId {
index: num_nodes - 1,
- spatial_id: SpatialId::new(num_nodes - 1, pipeline_id),
})
} else {
None
@@ -24,10 +24,10 @@ fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {
tree.add_scroll_tree_node(
parent.as_ref(),
- SpatialId::new(num_nodes, pipeline_id),
- Some(ScrollableNodeInfo {
+ SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo {
external_id: ExternalScrollId(num_nodes as u64, pipeline_id),
- scrollable_size: Size2D::new(100.0, 100.0),
+ content_rect: Size2D::new(200.0, 200.0).into(),
+ clip_rect: Size2D::new(100.0, 100.0).into(),
scroll_sensitivity: AxesScrollSensitivity {
x: ScrollSensitivity::ScriptAndInputEvents,
y: ScrollSensitivity::ScriptAndInputEvents,
@@ -78,8 +78,15 @@ fn test_scroll_tree_simple_scroll_chaining() {
let pipeline_id = PipelineId(0, 0);
let parent_id = add_mock_scroll_node(&mut scroll_tree);
- let unscrollable_child_id =
- scroll_tree.add_scroll_tree_node(Some(&parent_id), SpatialId::new(1, pipeline_id), None);
+ let unscrollable_child_id = scroll_tree.add_scroll_tree_node(
+ Some(&parent_id),
+ SpatialTreeNodeInfo::Sticky(StickyNodeInfo {
+ frame_rect: Size2D::new(100.0, 100.0).into(),
+ margins: SideOffsets2D::default(),
+ vertical_offset_bounds: StickyOffsetBounds::new(0.0, 0.0),
+ horizontal_offset_bounds: StickyOffsetBounds::new(0.0, 0.0),
+ }),
+ );
let (scrolled_id, offset) = scroll_tree
.scroll_node_or_ancestor(
@@ -157,16 +164,14 @@ fn test_scroll_tree_chain_through_overflow_hidden() {
let pipeline_id = PipelineId(0, 0);
let parent_id = add_mock_scroll_node(&mut scroll_tree);
let overflow_hidden_id = add_mock_scroll_node(&mut scroll_tree);
- scroll_tree
- .get_node_mut(&overflow_hidden_id)
- .scroll_info
- .as_mut()
- .map(|info| {
- info.scroll_sensitivity = AxesScrollSensitivity {
- x: ScrollSensitivity::Script,
- y: ScrollSensitivity::Script,
- };
- });
+ let node = scroll_tree.get_node_mut(&overflow_hidden_id);
+
+ if let SpatialTreeNodeInfo::Scroll(ref mut scroll_node_info) = node.info {
+ scroll_node_info.scroll_sensitivity = AxesScrollSensitivity {
+ x: ScrollSensitivity::Script,
+ y: ScrollSensitivity::Script,
+ };
+ }
let (scrolled_id, offset) = scroll_tree
.scroll_node_or_ancestor(
diff --git a/components/shared/constellation/lib.rs b/components/shared/constellation/lib.rs
index d85fbe31bdf..005295000c9 100644
--- a/components/shared/constellation/lib.rs
+++ b/components/shared/constellation/lib.rs
@@ -152,7 +152,7 @@ pub enum TraversalDirection {
}
/// A task on the <https://html.spec.whatwg.org/multipage/#port-message-queue>
-#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct PortMessageTask {
/// The origin of this task.
pub origin: ImmutableOrigin,
diff --git a/components/shared/constellation/structured_data/mod.rs b/components/shared/constellation/structured_data/mod.rs
index 3fb9d0c5f67..81e3849e476 100644
--- a/components/shared/constellation/structured_data/mod.rs
+++ b/components/shared/constellation/structured_data/mod.rs
@@ -20,7 +20,7 @@ pub use transferable::*;
/// A data-holder for serialized data and transferred objects.
/// <https://html.spec.whatwg.org/multipage/#structuredserializewithtransfer>
-#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
pub struct StructuredSerializedData {
/// Data serialized by SpiderMonkey.
pub serialized: Vec<u8>,
@@ -32,6 +32,8 @@ pub struct StructuredSerializedData {
pub exceptions: Option<HashMap<DomExceptionId, DomException>>,
/// Transferred objects.
pub ports: Option<HashMap<MessagePortId, MessagePortImpl>>,
+ /// Transform streams transferred objects.
+ pub transform_streams: Option<HashMap<MessagePortId, TransformStreamData>>,
}
impl StructuredSerializedData {
diff --git a/components/shared/constellation/structured_data/serializable.rs b/components/shared/constellation/structured_data/serializable.rs
index 194f0567c51..22370087665 100644
--- a/components/shared/constellation/structured_data/serializable.rs
+++ b/components/shared/constellation/structured_data/serializable.rs
@@ -88,7 +88,7 @@ impl Clone for BroadcastMsg {
}
/// File-based blob
-#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct FileBlob {
#[ignore_malloc_size_of = "Uuid are hard(not really)"]
id: Uuid,
@@ -164,7 +164,7 @@ impl BroadcastClone for BlobImpl {
}
/// The data backing a DOM Blob.
-#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct BlobImpl {
/// UUID of the blob.
blob_id: BlobId,
@@ -177,7 +177,7 @@ pub struct BlobImpl {
}
/// Different backends of Blob
-#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum BlobData {
/// File-based blob, whose content lives in the net process
File(FileBlob),
diff --git a/components/shared/constellation/structured_data/transferable.rs b/components/shared/constellation/structured_data/transferable.rs
index 528c1e79e65..3210a41a538 100644
--- a/components/shared/constellation/structured_data/transferable.rs
+++ b/components/shared/constellation/structured_data/transferable.rs
@@ -15,6 +15,12 @@ use strum::EnumIter;
use crate::PortMessageTask;
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
+pub struct TransformStreamData {
+ pub readable: (MessagePortId, MessagePortImpl),
+ pub writable: (MessagePortId, MessagePortImpl),
+}
+
/// All the DOM interfaces that can be transferred.
#[derive(Clone, Copy, Debug, EnumIter)]
pub enum Transferrable {
@@ -28,7 +34,7 @@ pub enum Transferrable {
TransformStream,
}
-#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
enum MessagePortState {
/// <https://html.spec.whatwg.org/multipage/#detached>
Detached,
@@ -42,7 +48,7 @@ enum MessagePortState {
Disabled(bool),
}
-#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
+#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
/// The data and logic backing the DOM managed MessagePort.
pub struct MessagePortImpl {
/// The current state of the port.
diff --git a/components/shared/embedder/resources.rs b/components/shared/embedder/resources.rs
index 830a403698e..28464a95d1a 100644
--- a/components/shared/embedder/resources.rs
+++ b/components/shared/embedder/resources.rs
@@ -116,7 +116,7 @@ impl Resource {
match self {
Resource::BluetoothBlocklist => "gatt_blocklist.txt",
Resource::DomainList => "public_domains.txt",
- Resource::HstsPreloadList => "hsts_preload.json",
+ Resource::HstsPreloadList => "hsts_preload.fstmap",
Resource::BadCertHTML => "badcert.html",
Resource::NetErrorHTML => "neterror.html",
Resource::RippyPNG => "rippy.png",
@@ -155,7 +155,7 @@ fn resources_for_tests() -> Box<dyn ResourceReaderMethods + Sync + Send> {
&include_bytes!("../../../resources/public_domains.txt")[..]
},
Resource::HstsPreloadList => {
- &include_bytes!("../../../resources/hsts_preload.json")[..]
+ &include_bytes!("../../../resources/hsts_preload.fstmap")[..]
},
Resource::BadCertHTML => &include_bytes!("../../../resources/badcert.html")[..],
Resource::NetErrorHTML => &include_bytes!("../../../resources/neterror.html")[..],
diff --git a/components/shared/net/Cargo.toml b/components/shared/net/Cargo.toml
index 79ea936a688..0dfad486455 100644
--- a/components/shared/net/Cargo.toml
+++ b/components/shared/net/Cargo.toml
@@ -19,6 +19,7 @@ compositing_traits = { workspace = true }
content-security-policy = { workspace = true }
cookie = { workspace = true }
crossbeam-channel = { workspace = true }
+data-url = { workspace = true }
embedder_traits = { workspace = true }
headers = { workspace = true }
http = { workspace = true }
diff --git a/components/shared/net/fetch/headers.rs b/components/shared/net/fetch/headers.rs
index 11bb68d5d0a..5ffd537adf8 100644
--- a/components/shared/net/fetch/headers.rs
+++ b/components/shared/net/fetch/headers.rs
@@ -3,8 +3,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::iter::Peekable;
-use std::str::Chars;
+use std::str::{Chars, FromStr};
+use data_url::mime::Mime as DataUrlMime;
use headers::HeaderMap;
/// <https://fetch.spec.whatwg.org/#http-tab-or-space>
@@ -184,3 +185,93 @@ fn collect_http_quoted_string(position: &mut Peekable<Chars>, extract_value: boo
// Step 6, 7
value
}
+
+/// <https://fetch.spec.whatwg.org/#concept-header-extract-mime-type>
+/// This function uses data_url::Mime to parse the MIME Type because
+/// mime::Mime does not provide a parser following the Fetch spec
+/// see <https://github.com/hyperium/mime/issues/106>
+pub fn extract_mime_type_as_dataurl_mime(headers: &HeaderMap) -> Option<DataUrlMime> {
+ // > 1: Let charset be null.
+ let mut charset = None;
+ // > 2: Let essence be null.
+ let mut essence = String::new();
+ // > 3: Let mimeType be null.
+ let mut mime_type = None;
+
+ // > 4: Let values be the result of getting, decoding, and splitting `Content-Type`
+ // from headers.
+ // > 5: If values is null, then return failure.
+ let headers_values = get_decode_and_split_header_name("content-type", headers)?;
+
+ // > 6: For each value of values:
+ for header_value in headers_values.iter() {
+ // > 6.1: Let temporaryMimeType be the result of parsing value.
+ match DataUrlMime::from_str(header_value) {
+ // > 6.2: If temporaryMimeType is failure or its essence is "*/*", then continue.
+ Err(_) => continue,
+ Ok(temp_mime) => {
+ let temp_essence = format!("{}/{}", temp_mime.type_, temp_mime.subtype);
+
+ // > 6.2: If temporaryMimeType is failure or its essence is "*/*", then
+ // continue.
+ if temp_essence == "*/*" {
+ continue;
+ }
+
+ // > 6.3: Set mimeType to temporaryMimeType.
+ mime_type = Some(DataUrlMime {
+ type_: temp_mime.type_.to_string(),
+ subtype: temp_mime.subtype.to_string(),
+ parameters: temp_mime.parameters.clone(),
+ });
+
+ // > 6.4: If mimeType’s essence is not essence, then:
+ let temp_charset = &temp_mime.get_parameter("charset");
+ if temp_essence != essence {
+ // > 6.4.1: Set charset to null.
+ // > 6.4.2: If mimeType’s parameters["charset"] exists, then set
+ // charset to mimeType’s parameters["charset"].
+ charset = temp_charset.map(|c| c.to_string());
+ // > 6.4.3: Set essence to mimeType’s essence.
+ essence = temp_essence.to_owned();
+ } else {
+ // > 6.5: Otherwise, if mimeType’s parameters["charset"] does not exist,
+ // and charset is non-null, set mimeType’s parameters["charset"] to charset.
+ if temp_charset.is_none() && charset.is_some() {
+ let DataUrlMime {
+ type_: t,
+ subtype: st,
+ parameters: p,
+ } = mime_type.unwrap();
+ let mut params = p;
+ params.push(("charset".to_string(), charset.clone().unwrap()));
+ mime_type = Some(DataUrlMime {
+ type_: t.to_string(),
+ subtype: st.to_string(),
+ parameters: params,
+ })
+ }
+ }
+ },
+ }
+ }
+
+ // > 7: If mimeType is null, then return failure.
+ // > 8: Return mimeType.
+ mime_type
+}
+
+pub fn extract_mime_type(headers: &HeaderMap) -> Option<Vec<u8>> {
+ extract_mime_type_as_dataurl_mime(headers).map(|m| format!("{}", m).into_bytes())
+}
+
+pub fn extract_mime_type_as_mime(headers: &HeaderMap) -> Option<mime::Mime> {
+ extract_mime_type_as_dataurl_mime(headers).and_then(|mime: DataUrlMime| {
+ // Try to transform a data-url::mime::Mime into a mime::Mime
+ let mut mime_as_str = format!("{}/{}", mime.type_, mime.subtype);
+ for p in mime.parameters {
+ mime_as_str.push_str(format!("; {}={}", p.0, p.1).as_str());
+ }
+ mime_as_str.parse().ok()
+ })
+}
diff --git a/components/shared/net/pub_domains.rs b/components/shared/net/pub_domains.rs
index cbbb2b465b2..6e6f883cd2f 100644
--- a/components/shared/net/pub_domains.rs
+++ b/components/shared/net/pub_domains.rs
@@ -19,9 +19,11 @@ use std::iter::FromIterator;
use std::sync::LazyLock;
use embedder_traits::resources::{self, Resource};
+use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
+use malloc_size_of_derive::MallocSizeOf;
use servo_url::{Host, ImmutableOrigin, ServoUrl};
-#[derive(Clone, Debug, Default)]
+#[derive(Clone, Debug, Default, MallocSizeOf)]
pub struct PubDomainRules {
rules: HashSet<String>,
wildcards: HashSet<String>,
@@ -30,6 +32,10 @@ pub struct PubDomainRules {
static PUB_DOMAINS: LazyLock<PubDomainRules> = LazyLock::new(load_pub_domains);
+pub fn public_suffix_list_size_of(ops: &mut MallocSizeOfOps) -> usize {
+ PUB_DOMAINS.size_of(ops)
+}
+
impl<'a> FromIterator<&'a str> for PubDomainRules {
fn from_iter<T>(iter: T) -> Self
where
diff --git a/components/shared/net/response.rs b/components/shared/net/response.rs
index f91993ddccb..9a01fbbf965 100644
--- a/components/shared/net/response.rs
+++ b/components/shared/net/response.rs
@@ -7,7 +7,6 @@
use std::sync::Mutex;
use std::sync::atomic::AtomicBool;
-use headers::{ContentType, HeaderMapExt};
use http::HeaderMap;
use hyper_serde::Serde;
use malloc_size_of_derive::MallocSizeOf;
@@ -15,6 +14,7 @@ use serde::{Deserialize, Serialize};
use servo_arc::Arc;
use servo_url::ServoUrl;
+use crate::fetch::headers::extract_mime_type_as_mime;
use crate::http_status::HttpStatus;
use crate::{
FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy, ResourceFetchTiming,
@@ -300,13 +300,7 @@ impl Response {
pub fn metadata(&self) -> Result<FetchMetadata, NetworkError> {
fn init_metadata(response: &Response, url: &ServoUrl) -> Metadata {
let mut metadata = Metadata::default(url.clone());
- metadata.set_content_type(
- response
- .headers
- .typed_get::<ContentType>()
- .map(|v| v.into())
- .as_ref(),
- );
+ metadata.set_content_type(extract_mime_type_as_mime(&response.headers).as_ref());
metadata.location_url.clone_from(&response.location_url);
metadata.headers = Some(Serde(response.headers.clone()));
metadata.status.clone_from(&response.status);
diff --git a/components/shared/net/storage_thread.rs b/components/shared/net/storage_thread.rs
index 0253603016e..2ba0aa12445 100644
--- a/components/shared/net/storage_thread.rs
+++ b/components/shared/net/storage_thread.rs
@@ -4,6 +4,7 @@
use ipc_channel::ipc::IpcSender;
use malloc_size_of_derive::MallocSizeOf;
+use profile_traits::mem::ReportsChan;
use serde::{Deserialize, Serialize};
use servo_url::ServoUrl;
@@ -45,4 +46,7 @@ pub enum StorageThreadMsg {
/// send a reply when done cleaning up thread resources and then shut it down
Exit(IpcSender<()>),
+
+ /// Measure memory used by this thread and send the report over the provided channel.
+ CollectMemoryReport(ReportsChan),
}