Skip to content

Commit 46c7804

Browse files
committed
feat: Support for the picture element
1 parent 42aa7f8 commit 46c7804

7 files changed

Lines changed: 458 additions & 16 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ style_traits = { version = "0.3", package = "stylo_traits" }
3030
style_config = { version = "0.3", package = "stylo_config" }
3131
style_dom = { version = "0.3", package = "stylo_dom" }
3232
selectors = { version = "0.28", package = "selectors" }
33+
cssparser = "0.35"
34+
mime = "0.3"
3335

3436
markup5ever = "0.16.1" # needs to match stylo web_atoms version
3537
html5ever = "0.31" # needs to match stylo web_atoms version

packages/blitz-dom/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ atomic_refcell = { workspace = true, features = ["serde"] }
4141
string_cache = { workspace = true }
4242
markup5ever = { workspace = true }
4343
smallvec = { workspace = true }
44+
cssparser = { workspace = true }
45+
mime = { workspace = true }
4446

4547
# DioxusLabs dependencies
4648
taffy = { workspace = true }

packages/blitz-dom/src/document.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use style::properties::ComputedValues;
2424
use style::properties::style_structs::Font;
2525
use style::values::GenericAtomIdent;
2626
use style::values::computed::Overflow;
27+
use style_traits::ParsingMode;
2728
// use quadtree_rs::Quadtree;
2829
use crate::net::{Resource, StylesheetLoader};
2930
use selectors::{Element, matching::QuirksMode};
@@ -41,9 +42,12 @@ use style::servo_arc::Arc as ServoArc;
4142
use style::{
4243
dom::{TDocument, TNode},
4344
media_queries::{Device, MediaList},
45+
parser::ParserContext,
4446
selector_parser::SnapshotMap,
4547
shared_lock::{SharedRwLock, StylesheetGuards},
46-
stylesheets::{AllowImportRules, DocumentStyleSheet, Origin, Stylesheet, UrlExtraData},
48+
stylesheets::{
49+
AllowImportRules, CssRuleType, DocumentStyleSheet, Origin, Stylesheet, UrlExtraData,
50+
},
4751
stylist::Stylist,
4852
};
4953
use taffy::AvailableSpace;
@@ -1280,6 +1284,32 @@ impl BaseDocument {
12801284
);
12811285
chain
12821286
}
1287+
1288+
/// https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
1289+
pub fn match_media(&self, media_query_string: &str) -> bool {
1290+
let mut input = cssparser::ParserInput::new(media_query_string);
1291+
let mut parser = cssparser::Parser::new(&mut input);
1292+
1293+
let url_data = UrlExtraData::from(
1294+
self.base_url
1295+
.clone()
1296+
.unwrap_or_else(|| "about:blank".parse::<Url>().unwrap()),
1297+
);
1298+
let quirks_mode = self.stylist.quirks_mode();
1299+
let context = ParserContext::new(
1300+
Origin::Author,
1301+
&url_data,
1302+
Some(CssRuleType::Style),
1303+
ParsingMode::all(),
1304+
quirks_mode,
1305+
Default::default(),
1306+
None,
1307+
None,
1308+
);
1309+
1310+
let media_list = MediaList::parse(&context, &mut parser);
1311+
media_list.evaluate(self.stylist.device(), quirks_mode)
1312+
}
12831313
}
12841314

12851315
impl AsRef<BaseDocument> for BaseDocument {

packages/blitz-dom/src/mutator.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ use std::collections::HashSet;
22
use std::ops::{Deref, DerefMut};
33

44
use crate::document::make_device;
5-
use crate::net::{CssHandler, ImageHandler};
5+
use crate::net::CssHandler;
66
use crate::node::NodeSpecificData;
7-
use crate::util::ImageType;
87
use crate::{Attribute, BaseDocument, ElementNodeData, NodeData, QualName, local_name, ns};
98
use blitz_traits::Viewport;
109
use blitz_traits::net::Request;
@@ -90,6 +89,7 @@ impl DocumentMutator<'_> {
9089
let child_ids = std::mem::take(&mut self.doc.nodes[old_parent_id].children);
9190
self.maybe_record_node(old_parent_id);
9291
self.append_children(new_parent_id, &child_ids);
92+
self.maybe_load_image(&child_ids);
9393
}
9494

9595
pub fn append_children(&mut self, parent_id: usize, child_ids: &[usize]) {
@@ -105,6 +105,7 @@ impl DocumentMutator<'_> {
105105
}
106106

107107
self.maybe_record_node(parent_id);
108+
self.maybe_load_image(child_ids);
108109
}
109110

110111
pub fn replace_node_with(&mut self, anchor_node_id: usize, new_node_ids: &[usize]) {
@@ -143,11 +144,13 @@ impl DocumentMutator<'_> {
143144
}
144145

145146
self.maybe_record_parent_node(anchor_node_id);
147+
self.maybe_load_image(new_node_ids);
146148
}
147149

148150
pub fn insert_nodes_before(&mut self, anchor_node_id: usize, new_node_ids: &[usize]) {
149151
self.doc.insert_before(anchor_node_id, new_node_ids);
150152
self.maybe_record_parent_node(anchor_node_id);
153+
self.maybe_load_image(new_node_ids);
151154
}
152155

153156
pub fn remove_node_if_unparented(&mut self, node_id: usize) {
@@ -217,7 +220,7 @@ impl DocumentMutator<'_> {
217220
match tag {
218221
"title" => self.title_node = Some(id),
219222
"link" => self.load_linked_stylesheet(id),
220-
"img" => self.load_image(id),
223+
// "img" => self.doc.load_image(id),
221224
"style" => {
222225
self.style_nodes.insert(id);
223226
}
@@ -262,7 +265,8 @@ impl DocumentMutator<'_> {
262265
};
263266

264267
let attr = name.local.as_ref();
265-
let load_image = element.name.local == local_name!("img") && attr == "src";
268+
let load_image =
269+
element.name.local == local_name!("img") && (attr == "src" || attr == "srcset");
266270

267271
if element.name.local == local_name!("input") && attr == "checked" {
268272
set_input_checked_state(element, value.to_string());
@@ -291,7 +295,7 @@ impl DocumentMutator<'_> {
291295
}
292296

293297
if load_image {
294-
self.load_image(node_id);
298+
self.doc.load_image(node_id);
295299
}
296300
}
297301

@@ -397,16 +401,16 @@ impl<'doc> DocumentMutator<'doc> {
397401
);
398402
}
399403

400-
fn load_image(&mut self, target_id: usize) {
401-
let node = &self.doc.nodes[target_id];
402-
if let Some(raw_src) = node.attr(local_name!("src")) {
403-
if !raw_src.is_empty() {
404-
let src = self.doc.resolve_url(raw_src);
405-
self.doc.net_provider.fetch(
406-
self.doc.id(),
407-
Request::get(src),
408-
Box::new(ImageHandler::new(target_id, ImageType::Image)),
409-
);
404+
fn is_img_node(&self, node_id: usize) -> bool {
405+
self.doc.nodes[node_id]
406+
.data
407+
.is_element_with_tag_name(&local_name!("img"))
408+
}
409+
410+
fn maybe_load_image(&self, node_ids: &[usize]) {
411+
for id in node_ids.iter() {
412+
if self.is_img_node(*id) {
413+
self.doc.load_image(*id);
410414
}
411415
}
412416
}

packages/blitz-dom/src/node.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ use url::Url;
3737
use crate::layout::table::TableContext;
3838
use blitz_traits::{BlitzMouseButtonEvent, DomEventData, HitResult};
3939

40+
pub mod image;
41+
4042
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4143
pub enum DisplayOuter {
4244
Block,

0 commit comments

Comments
 (0)