From 3f9211c6c1f60ed3fffcde61b2faf32ead88a822 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 19 May 2026 05:49:59 +0000 Subject: [PATCH 01/13] Step 0: wire appthere-ui into iris workspace and fix AtHomeTab props - Add appthere-ui to workspace members and workspace.dependencies - Remove thiserror from appthere-ui (unused dep, OQ-F) - Add pick_error_prefix and viewport_width_px props to AtHomeTabProps (OQ-A, OQ-D) - Update iris-app/Cargo.toml with Phase 2 dependencies (appthere-ui, tracing-subscriber) https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn --- Cargo.lock | 13 +++++++++---- Cargo.toml | 4 ++++ crates/appthere-ui/Cargo.toml | 1 - .../appthere-ui/src/components/home_tab/mod.rs | 10 ++++++++-- crates/iris-app/Cargo.toml | 16 +++++++--------- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5be5c8d..0458431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,6 +286,13 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "appthere-ui" +version = "0.1.0" +dependencies = [ + "dioxus", +] + [[package]] name = "arbitrary" version = "1.4.2" @@ -3264,14 +3271,12 @@ dependencies = [ name = "iris-app" version = "0.1.0" dependencies = [ + "appthere-ui", "dioxus", - "iris-aif", "iris-canvas", - "iris-ops", "iris-pixel", - "iris-plugin-api", - "iris-vector", "tracing", + "tracing-subscriber", "uuid", ] diff --git a/Cargo.toml b/Cargo.toml index d4ba48d..65bc724 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" exclude = ["crates/loki-file-access", "crates/loki-opc", "crates/appthere-canvas"] members = [ + "crates/appthere-ui", "crates/iris-app", "crates/iris-canvas", "crates/iris-pixel", @@ -31,6 +32,9 @@ appthere-color = { version = "0.1" } appthere-file-access = { package = "loki-file-access", path = "crates/loki-file-access" } loki-opc = { path = "crates/loki-opc", features = ["serde"] } +# AppThere UI shared crate +appthere-ui = { path = "crates/appthere-ui" } + # Iris internal crates (path deps within this workspace) iris-ops = { path = "crates/iris-ops" } iris-pixel = { path = "crates/iris-pixel" } diff --git a/crates/appthere-ui/Cargo.toml b/crates/appthere-ui/Cargo.toml index 37919d3..25d1871 100644 --- a/crates/appthere-ui/Cargo.toml +++ b/crates/appthere-ui/Cargo.toml @@ -12,4 +12,3 @@ path = "src/lib.rs" [dependencies] dioxus = { workspace = true } -thiserror = { workspace = true } diff --git a/crates/appthere-ui/src/components/home_tab/mod.rs b/crates/appthere-ui/src/components/home_tab/mod.rs index 9071b31..1f300be 100644 --- a/crates/appthere-ui/src/components/home_tab/mod.rs +++ b/crates/appthere-ui/src/components/home_tab/mod.rs @@ -67,7 +67,7 @@ pub struct RecentDocument { /// All interactive elements (template cards, document rows, buttons) meet this. #[component] pub fn AtHomeTab(props: AtHomeTabProps) -> Element { - let viewport_width = use_signal(|| 375.0_f32); + let viewport_width = use_signal(|| props.viewport_width_px); let is_desktop = viewport_width() >= BREAKPOINT_DESKTOP_PX; // Holds the last file-picker error message, if any. @@ -201,7 +201,7 @@ pub fn AtHomeTab(props: AtHomeTabProps) -> Element { fg = COLOR_STATUS_ERROR_TEXT, size = FONT_SIZE_LABEL, ), - "Could not open file picker: {err}" + "{props.pick_error_prefix}: {err}" } } @@ -262,6 +262,12 @@ pub struct AtHomeTabProps { /// Message shown when `recent_documents` is empty. pub empty_recent_label: String, + // COMPAT(loki): loki-text's AtHomeTab call sites need updating to pass pick_error_prefix and viewport_width_px props + /// Prefix for the file-picker error banner. + pub pick_error_prefix: String, + /// Viewport width in CSS pixels, used for responsive layout detection. + pub viewport_width_px: f32, + // ── Callbacks ───────────────────────────────────────────────────────────── /// Called when a template card is selected. Argument is the index into `templates`. pub on_template_select: EventHandler, diff --git a/crates/iris-app/Cargo.toml b/crates/iris-app/Cargo.toml index d1f179f..885b586 100644 --- a/crates/iris-app/Cargo.toml +++ b/crates/iris-app/Cargo.toml @@ -12,12 +12,10 @@ name = "iris" path = "src/main.rs" [dependencies] -iris-canvas = { workspace = true } -iris-pixel = { workspace = true } -iris-vector = { workspace = true } -iris-ops = { workspace = true } -iris-aif = { workspace = true } -iris-plugin-api = { workspace = true } -dioxus = { workspace = true } -tracing = { workspace = true } -uuid = { workspace = true } +appthere-ui = { workspace = true } +iris-canvas = { workspace = true } +iris-pixel = { workspace = true } +dioxus = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +uuid = { workspace = true } From 9c70e22e45c00c5f03d96ae5b3de80ab70c5b0ed Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 19 May 2026 06:02:37 +0000 Subject: [PATCH 02/13] feat(iris-app): Phase 2 panels + canvas layout Implements the full iris-app shell using appthere_ui components: - state.rs: AppState, OpenDocument, ToolMode, detect_platform() - app.rs: root App component with AtThemeContext injection - layout.rs: AppLayout composing AtTitleBar, AtTabBar, and body panels - home_tab.rs: IrisHomeTab wrapping AtHomeTab with Iris templates - ribbon.rs: IrisRibbon with Edit/Adjustments/Export tabs (text label placeholders) - tool_palette.rs: ToolPalette left sidebar with Pixel/Vector mode toggle - canvas_area.rs: CanvasArea mounting IrisCanvas with viewport sync - layers_panel.rs: LayersPanel right sidebar with add/remove/visibility controls - status_bar.rs: IrisStatusBar repurposing AtStatusBar for layer count + canvas dims - main.rs: tracing init + dioxus::launch(App) All files under 300 lines. cargo check --workspace clean. All tests pass. https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn --- crates/iris-app/src/app.rs | 17 +++ crates/iris-app/src/canvas_area.rs | 64 +++++++++++ crates/iris-app/src/home_tab.rs | 59 ++++++++++ crates/iris-app/src/layers_panel.rs | 171 ++++++++++++++++++++++++++++ crates/iris-app/src/layout.rs | 76 +++++++++++++ crates/iris-app/src/main.rs | 24 +++- crates/iris-app/src/ribbon.rs | 87 ++++++++++++++ crates/iris-app/src/state.rs | 100 ++++++++++++++++ crates/iris-app/src/status_bar.rs | 34 ++++++ crates/iris-app/src/tool_palette.rs | 72 ++++++++++++ 10 files changed, 698 insertions(+), 6 deletions(-) create mode 100644 crates/iris-app/src/app.rs create mode 100644 crates/iris-app/src/canvas_area.rs create mode 100644 crates/iris-app/src/home_tab.rs create mode 100644 crates/iris-app/src/layers_panel.rs create mode 100644 crates/iris-app/src/layout.rs create mode 100644 crates/iris-app/src/ribbon.rs create mode 100644 crates/iris-app/src/state.rs create mode 100644 crates/iris-app/src/status_bar.rs create mode 100644 crates/iris-app/src/tool_palette.rs diff --git a/crates/iris-app/src/app.rs b/crates/iris-app/src/app.rs new file mode 100644 index 0000000..6dd87fb --- /dev/null +++ b/crates/iris-app/src/app.rs @@ -0,0 +1,17 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::AtThemeContext; +use dioxus::prelude::*; + +use crate::layout::AppLayout; +use crate::state::AppState; + +#[component] +pub fn App() -> Element { + provide_context(AtThemeContext::default()); + let state = use_signal(AppState::default); + rsx! { + AppLayout { state } + } +} diff --git a/crates/iris-app/src/canvas_area.rs b/crates/iris-app/src/canvas_area.rs new file mode 100644 index 0000000..c46b09d --- /dev/null +++ b/crates/iris-app/src/canvas_area.rs @@ -0,0 +1,64 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::tokens::colors::{COLOR_SURFACE_BASE, COLOR_TEXT_ON_CHROME_SECONDARY}; +use appthere_ui::tokens::typography::FONT_SIZE_BODY; +use dioxus::prelude::*; +use iris_canvas::IrisCanvas; +use iris_pixel::LayerTree; + +use crate::state::AppState; + +// TODO(iris): SPEC.md §11.3 — measure actual CanvasArea dimensions via onmounted +const CANVAS_WIDTH: u32 = 800; +const CANVAS_HEIGHT: u32 = 600; + +#[component] +pub fn CanvasArea(mut state: Signal) -> Element { + // All hooks called unconditionally before any early return (Dioxus rules). + let tree_signal = use_signal(move || { + state.read().document.as_ref() + .map(|d| d.tree.clone()) + .unwrap_or_else(|| LayerTree::new(1, 1, 96.0, 96.0)) + }); + + let viewport_signal = use_signal(move || { + state.read().document.as_ref() + .map(|d| d.viewport.clone()) + .unwrap_or_default() + }); + + use_effect(move || { + let vp = viewport_signal.read().clone(); + if let Some(doc) = state.write().document.as_mut() { + doc.viewport = vp; + } + }); + + let doc_exists = state.read().document.is_some(); + + // Early return AFTER all hooks. + if !doc_exists { + return rsx! { + div { + style: "flex: 1; display: flex; align-items: center; \ + justify-content: center; background-color: {COLOR_SURFACE_BASE}; \ + color: {COLOR_TEXT_ON_CHROME_SECONDARY}; \ + font-size: {FONT_SIZE_BODY}px;", + "No document open" + } + }; + } + + rsx! { + div { + style: "flex: 1; overflow: hidden; background-color: {COLOR_SURFACE_BASE};", + IrisCanvas { + tree: tree_signal, + viewport: viewport_signal, + width: CANVAS_WIDTH, + height: CANVAS_HEIGHT, + } + } + } +} diff --git a/crates/iris-app/src/home_tab.rs b/crates/iris-app/src/home_tab.rs new file mode 100644 index 0000000..bdce213 --- /dev/null +++ b/crates/iris-app/src/home_tab.rs @@ -0,0 +1,59 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::{AtHomeTab, BuiltinTemplate}; +use dioxus::prelude::*; + +use crate::state::{AppState, OpenDocument}; + +#[component] +pub fn IrisHomeTab(mut state: Signal) -> Element { + let templates = vec![ + BuiltinTemplate { + name: "Blank Canvas".to_string(), + description: String::new(), + format_label: "AIF".to_string(), + }, + BuiltinTemplate { + name: "A4 Photo".to_string(), + description: String::new(), + format_label: "AIF".to_string(), + }, + BuiltinTemplate { + name: "Social Media".to_string(), + description: String::new(), + format_label: "AIF".to_string(), + }, + ]; + + // TODO(iris): SPEC.md §11 — measure actual window width for responsive layout + let viewport_width_px = 1280.0_f32; + + rsx! { + AtHomeTab { + app_name: "Iris".to_string(), + templates, + recent_documents: vec![], + templates_label: "Start from a template".to_string(), + recent_label: "Recent documents".to_string(), + browse_label: "Browse templates".to_string(), + open_file_label: "Open file".to_string(), + empty_recent_label: "No recent files".to_string(), + pick_error_prefix: "Could not open file".to_string(), + viewport_width_px, + on_template_select: move |_idx| { + let doc = OpenDocument::new_blank(800, 600, "Untitled"); + state.write().document = Some(doc); + state.write().active_tab_index = 1; + }, + on_browse_templates: move |_| {}, + on_recent_open: move |_| {}, + on_open_file: move |_| { + // TODO(iris): Phase 3 — wire async file picker with appthere_file_access + let doc = OpenDocument::new_blank(800, 600, "Untitled"); + state.write().document = Some(doc); + state.write().active_tab_index = 1; + }, + } + } +} diff --git a/crates/iris-app/src/layers_panel.rs b/crates/iris-app/src/layers_panel.rs new file mode 100644 index 0000000..c58c4e8 --- /dev/null +++ b/crates/iris-app/src/layers_panel.rs @@ -0,0 +1,171 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::tokens::colors::{ + COLOR_ACCENT_PRIMARY, COLOR_BORDER_CHROME, COLOR_SURFACE_1, COLOR_SURFACE_2, + COLOR_SURFACE_CHROME, COLOR_TEXT_ON_CHROME, +}; +use appthere_ui::tokens::spacing::{RADIUS_SM, SPACE_2, SPACE_3}; +use appthere_ui::tokens::typography::{FONT_SIZE_BODY, FONT_SIZE_LABEL, FONT_WEIGHT_SEMIBOLD}; +use dioxus::prelude::*; +use iris_pixel::{ + BitDepth, BlendMode, ChannelLayout, ExrCompression, Layer, LayerContent, LayerId, PixelLayer, + TileCache, LINEAR_SRGB, +}; + +use crate::state::AppState; + +// TODO(iris): move LAYERS_PANEL_WIDTH to appthere_ui layout tokens +const LAYERS_PANEL_WIDTH: f32 = 240.0; + +#[component] +pub fn LayersPanel(mut state: Signal) -> Element { + rsx! { + div { + style: "width: {LAYERS_PANEL_WIDTH}px; background-color: {COLOR_SURFACE_1}; \ + display: flex; flex-direction: column; flex-shrink: 0; \ + border-left: 1px solid {COLOR_BORDER_CHROME}; box-sizing: border-box;", + div { + style: "padding: {SPACE_2}px {SPACE_3}px; \ + background-color: {COLOR_SURFACE_CHROME}; \ + color: {COLOR_TEXT_ON_CHROME}; \ + font-size: {FONT_SIZE_LABEL}px; \ + font-weight: {FONT_WEIGHT_SEMIBOLD}; \ + border-bottom: 1px solid {COLOR_BORDER_CHROME};", + "Layers" + } + div { + style: "flex: 1; overflow-y: auto;", + { + let layer_ids: Vec = state.read().document.as_ref() + .map(|d| d.tree.iter_depth_first().map(|l| l.id).collect()) + .unwrap_or_default(); + rsx! { + for id in layer_ids { + { + let name = state.read().document.as_ref() + .and_then(|d| d.tree.get(id)) + .map(|l| l.name.clone()) + .unwrap_or_default(); + let visible = state.read().document.as_ref() + .and_then(|d| d.tree.get(id)) + .map(|l| l.visible) + .unwrap_or(true); + let selected = state.read().selected_layer == Some(id); + rsx! { + LayerRow { + key: "{id}", + layer_id: id, + name, + visible, + selected, + state, + } + } + } + } + } + } + } + div { + style: "padding: {SPACE_2}px; display: flex; gap: {SPACE_2}px; \ + border-top: 1px solid {COLOR_BORDER_CHROME};", + button { + style: "flex: 1; padding: {SPACE_2}px; \ + background-color: {COLOR_ACCENT_PRIMARY}; \ + color: {COLOR_TEXT_ON_CHROME}; border: none; \ + border-radius: {RADIUS_SM}px; cursor: pointer; \ + font-size: {FONT_SIZE_LABEL}px;", + onclick: move |_| { + if let Some(doc) = state.write().document.as_mut() { + let layer = build_blank_pixel_layer("Layer"); + let _ = doc.tree.add_layer(None, 0, layer); + doc.dirty = true; + } + }, + "+" + } + button { + style: "flex: 1; padding: {SPACE_2}px; \ + background-color: {COLOR_SURFACE_2}; \ + color: {COLOR_TEXT_ON_CHROME}; border: none; \ + border-radius: {RADIUS_SM}px; cursor: pointer; \ + font-size: {FONT_SIZE_LABEL}px;", + onclick: move |_| { + let selected_id = state.read().selected_layer; + if let Some(sid) = selected_id { + if let Some(doc) = state.write().document.as_mut() { + let _ = doc.tree.remove_layer(sid); + doc.dirty = true; + } + state.write().selected_layer = None; + } + }, + "−" + } + } + } + } +} + +#[component] +fn LayerRow( + layer_id: LayerId, + name: String, + visible: bool, + selected: bool, + mut state: Signal, +) -> Element { + let bg = if selected { COLOR_ACCENT_PRIMARY } else { COLOR_SURFACE_1 }; + rsx! { + div { + style: "display: flex; align-items: center; padding: {SPACE_2}px {SPACE_3}px; \ + background-color: {bg}; cursor: pointer; \ + border-bottom: 1px solid {COLOR_BORDER_CHROME};", + onclick: move |_| state.write().selected_layer = Some(layer_id), + button { + style: "background: none; border: none; cursor: pointer; \ + color: {COLOR_TEXT_ON_CHROME}; margin-right: {SPACE_2}px; \ + font-size: {FONT_SIZE_LABEL}px; padding: 0;", + onclick: move |evt| { + evt.stop_propagation(); + if let Some(doc) = state.write().document.as_mut() { + if let Some(layer) = doc.tree.get_mut(layer_id) { + layer.visible = !layer.visible; + doc.dirty = true; + } + } + }, + if visible { "●" } else { "○" } + } + span { + style: "flex: 1; overflow: hidden; color: {COLOR_TEXT_ON_CHROME}; \ + font-size: {FONT_SIZE_BODY}px;", + "{name}" + } + } + } +} + +fn build_blank_pixel_layer(name: &str) -> Layer { + Layer { + id: uuid::Uuid::new_v4(), + name: name.to_string(), + visible: true, + locked: false, + opacity: 1.0, + blend_mode: BlendMode::Normal, + clipping_mask: false, + mask: None, + content: LayerContent::Pixel(PixelLayer { + channel_layout: ChannelLayout::Rgba, + bit_depth: BitDepth::F16, + color_space: LINEAR_SRGB, + compression: ExrCompression::Zip, + canvas_offset_x: 0, + canvas_offset_y: 0, + crop_bounds: None, + tiles: TileCache::default(), + }), + } +} diff --git a/crates/iris-app/src/layout.rs b/crates/iris-app/src/layout.rs new file mode 100644 index 0000000..3af0540 --- /dev/null +++ b/crates/iris-app/src/layout.rs @@ -0,0 +1,76 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::tokens::colors::COLOR_SURFACE_BASE; +use appthere_ui::tokens::typography::FONT_FAMILY_UI; +use appthere_ui::{AtDocumentTabData, AtTabBar, AtTitleBar}; +use dioxus::prelude::*; + +use crate::canvas_area::CanvasArea; +use crate::home_tab::IrisHomeTab; +use crate::layers_panel::LayersPanel; +use crate::ribbon::IrisRibbon; +use crate::state::{AppState, OpenDocument}; +use crate::status_bar::IrisStatusBar; +use crate::tool_palette::ToolPalette; + +#[component] +pub fn AppLayout(mut state: Signal) -> Element { + let tabs: Vec = state.read().document.as_ref().map(|doc| { + vec![AtDocumentTabData { + title: doc.title.clone(), + is_dirty: doc.dirty, + is_discarded: false, + }] + }).unwrap_or_default(); + + let active_idx = state.read().active_tab_index; + let platform = state.read().platform; + let title = state.read().document.as_ref() + .map(|d| d.title.clone()); + let is_dirty = state.read().document.as_ref() + .map(|d| d.dirty) + .unwrap_or(false); + + rsx! { + div { + style: "display: flex; flex-direction: column; width: 100%; height: 100vh; \ + background-color: {COLOR_SURFACE_BASE}; font-family: {FONT_FAMILY_UI};", + AtTitleBar { + document_title: title, + is_dirty, + app_name: "Iris", + collaborator_count: 0, + collaborator_label: String::new(), + platform, + on_icon_press: move |_| {}, + } + AtTabBar { + tabs, + active_index: active_idx, + home_tab_label: "Home".to_string(), + aria_label: "Document tabs".to_string(), + on_tab_select: move |idx| state.write().active_tab_index = idx, + on_tab_close: move |_| {}, + on_new_tab: move |_| { + let doc = OpenDocument::new_blank(800, 600, "Untitled"); + state.write().document = Some(doc); + state.write().active_tab_index = 1; + }, + new_tab_aria_label: "New document".to_string(), + } + if active_idx == 0 { + IrisHomeTab { state } + } else { + IrisRibbon { state } + div { + style: "display: flex; flex: 1; overflow: hidden;", + ToolPalette { state } + CanvasArea { state } + LayersPanel { state } + } + IrisStatusBar { state } + } + } + } +} diff --git a/crates/iris-app/src/main.rs b/crates/iris-app/src/main.rs index 9689dfa..994e026 100644 --- a/crates/iris-app/src/main.rs +++ b/crates/iris-app/src/main.rs @@ -1,11 +1,23 @@ -// Copyright 2026 AppThere Project +// Copyright 2024 AppThere Project // SPDX-License-Identifier: Apache-2.0 -//! AppThere Iris — application entry point. -//! -//! See SPEC.md §11 and crates/iris-app/BRIEF.md before implementing. +mod app; +mod canvas_area; +mod home_tab; +mod layers_panel; +mod layout; +mod ribbon; +mod state; +mod status_bar; +mod tool_palette; + +use app::App; fn main() { - // TODO(iris): SPEC.md §11 — Dioxus Native launch; stub only - println!("AppThere Iris — not yet implemented"); + tracing_subscriber::fmt() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .init(); + + tracing::info!("AppThere Iris starting"); + dioxus::launch(App); } diff --git a/crates/iris-app/src/ribbon.rs b/crates/iris-app/src/ribbon.rs new file mode 100644 index 0000000..b75c69d --- /dev/null +++ b/crates/iris-app/src/ribbon.rs @@ -0,0 +1,87 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::{AtRibbon, AtRibbonGroup, AtRibbonIconButton, RibbonTabDesc, RibbonTabIndex}; +use dioxus::prelude::*; + +use crate::state::AppState; + +#[component] +pub fn IrisRibbon(state: Signal) -> Element { + let tabs = vec![ + RibbonTabDesc { label: "Edit".to_string(), is_contextual: false, aria_label: None }, + RibbonTabDesc { label: "Adjustments".to_string(), is_contextual: false, aria_label: None }, + RibbonTabDesc { label: "Export".to_string(), is_contextual: false, aria_label: None }, + ]; + let mut active_tab = use_signal(|| 0_usize); + + rsx! { + AtRibbon { + tabs, + active_tab: *active_tab.read(), + on_tab_select: move |idx: RibbonTabIndex| *active_tab.write() = idx, + tab_content: rsx! { + if *active_tab.read() == 0 { + AtRibbonGroup { + label: Some("Tools".to_string()), + aria_label: "Tools group".to_string(), + AtRibbonIconButton { + icon_label: "B".to_string(), + aria_label: "Brush".to_string(), + is_active: false, + is_disabled: true, + on_click: move |_| {}, + // TODO(iris): Phase 3 — activate brush tool + } + AtRibbonIconButton { + icon_label: "E".to_string(), + aria_label: "Eraser".to_string(), + is_active: false, + is_disabled: true, + on_click: move |_| {}, + } + } + AtRibbonGroup { + label: Some("Selection".to_string()), + aria_label: "Selection group".to_string(), + AtRibbonIconButton { + icon_label: "M".to_string(), + aria_label: "Rectangular marquee".to_string(), + is_active: false, + is_disabled: true, + on_click: move |_| {}, + } + } + } + if *active_tab.read() == 1 { + AtRibbonGroup { + label: Some("Colour".to_string()), + aria_label: "Colour adjustment group".to_string(), + AtRibbonIconButton { + icon_label: "Lv".to_string(), + aria_label: "Levels".to_string(), + is_active: false, + is_disabled: true, + on_click: move |_| {}, + // TODO(iris): Phase 4 — adjustment layers + } + } + } + if *active_tab.read() == 2 { + AtRibbonGroup { + label: Some("Export".to_string()), + aria_label: "Export group".to_string(), + AtRibbonIconButton { + icon_label: "Ex".to_string(), + aria_label: "Export".to_string(), + is_active: false, + is_disabled: true, + on_click: move |_| {}, + // TODO(iris): Phase 4 — export pipeline + } + } + } + }, + } + } +} diff --git a/crates/iris-app/src/state.rs b/crates/iris-app/src/state.rs new file mode 100644 index 0000000..8f5770b --- /dev/null +++ b/crates/iris-app/src/state.rs @@ -0,0 +1,100 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::Platform; +use iris_canvas::CanvasViewport; +use iris_pixel::{ + BitDepth, BlendMode, ChannelLayout, ExrCompression, Layer, LayerContent, LayerId, LayerTree, + PixelLayer, TileCache, LINEAR_SRGB, +}; + +#[derive(Clone)] +pub struct AppState { + pub document: Option, + pub tool_mode: ToolMode, + pub selected_layer: Option, + pub active_tab_index: usize, + pub platform: Platform, +} + +#[derive(Clone)] +pub struct OpenDocument { + pub title: String, + // TODO(iris): SPEC.md §11 — Phase 3: populated by file-picker integration + #[allow(dead_code)] // Phase 3 — file picker not yet wired + pub path: Option, + pub tree: LayerTree, + pub viewport: CanvasViewport, + pub dirty: bool, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ToolMode { + Pixel, + Vector, +} + +impl Default for AppState { + fn default() -> Self { + Self { + document: Some(OpenDocument::new_blank(800, 600, "Untitled")), + tool_mode: ToolMode::Pixel, + selected_layer: None, + active_tab_index: 1, + platform: detect_platform(), + } + } +} + +impl OpenDocument { + pub fn new_blank(width_px: u32, height_px: u32, title: &str) -> Self { + let mut tree = LayerTree::new(width_px, height_px, 96.0, 96.0); + let layer = Layer { + id: uuid::Uuid::new_v4(), + name: "Background".to_string(), + visible: true, + locked: false, + opacity: 1.0, + blend_mode: BlendMode::Normal, + clipping_mask: false, + mask: None, + content: LayerContent::Pixel(PixelLayer { + channel_layout: ChannelLayout::Rgba, + bit_depth: BitDepth::F16, + color_space: LINEAR_SRGB, + compression: ExrCompression::Zip, + canvas_offset_x: 0, + canvas_offset_y: 0, + crop_bounds: None, + tiles: TileCache::default(), + }), + }; + tree.add_layer(None, 0, layer) + .expect("new_blank: adding initial layer to empty tree cannot fail"); + Self { + title: title.to_string(), + path: None, + tree, + viewport: CanvasViewport::new(), + dirty: false, + } + } + + pub fn zoom_percent(&self) -> u32 { + (self.viewport.zoom * 100.0).round() as u32 + } +} + +pub fn detect_platform() -> Platform { + if cfg!(target_os = "macos") { + Platform::MacOs + } else if cfg!(target_os = "windows") { + Platform::Windows + } else if cfg!(target_os = "android") { + Platform::Android + } else if cfg!(target_os = "ios") { + Platform::Ios + } else { + Platform::Linux + } +} diff --git a/crates/iris-app/src/status_bar.rs b/crates/iris-app/src/status_bar.rs new file mode 100644 index 0000000..18853b7 --- /dev/null +++ b/crates/iris-app/src/status_bar.rs @@ -0,0 +1,34 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::AtStatusBar; +use dioxus::prelude::*; + +use crate::state::AppState; + +#[component] +pub fn IrisStatusBar(mut state: Signal) -> Element { + let (layer_count, canvas_dims, zoom) = { + let s = state.read(); + let doc = s.document.as_ref(); + let layers = doc.map(|d| d.tree.root_layer_ids().len()).unwrap_or(0); + let dims = doc.map(|d| { + format!("{}×{}", d.tree.canvas_width, d.tree.canvas_height) + }).unwrap_or_default(); + let zoom = doc.map(|d| d.zoom_percent()).unwrap_or(100); + (layers, dims, zoom) + }; + + rsx! { + AtStatusBar { + page_label: format!("{layer_count} layer{}", if layer_count == 1 { "" } else { "s" }), + word_count_label: canvas_dims, + language_label: String::new(), + zoom_percent: zoom, + collaborator_count: 0, + collaborator_label: String::new(), + on_zoom_click: move |_| {}, + zoom_aria_label: "Zoom level".to_string(), + } + } +} diff --git a/crates/iris-app/src/tool_palette.rs b/crates/iris-app/src/tool_palette.rs new file mode 100644 index 0000000..25a9f9e --- /dev/null +++ b/crates/iris-app/src/tool_palette.rs @@ -0,0 +1,72 @@ +// Copyright 2024 AppThere Project +// SPDX-License-Identifier: Apache-2.0 + +use appthere_ui::tokens::colors::{ + COLOR_ACCENT_PRIMARY, COLOR_BORDER_CHROME, COLOR_SURFACE_1, COLOR_TEXT_ON_CHROME, + COLOR_TEXT_ON_CHROME_SECONDARY, +}; +use appthere_ui::tokens::spacing::{RADIUS_SM, SPACE_2}; +use appthere_ui::tokens::typography::{FONT_SIZE_LABEL, FONT_WEIGHT_SEMIBOLD}; +use dioxus::prelude::*; + +use crate::state::{AppState, ToolMode}; + +// TODO(iris): move TOOL_PALETTE_WIDTH to appthere_ui layout tokens +const TOOL_PALETTE_WIDTH: f32 = 56.0; + +#[component] +pub fn ToolPalette(mut state: Signal) -> Element { + let tool_mode = state.read().tool_mode; + + let pixel_bg = if tool_mode == ToolMode::Pixel { COLOR_ACCENT_PRIMARY } else { COLOR_SURFACE_1 }; + let vector_bg = if tool_mode == ToolMode::Vector { COLOR_ACCENT_PRIMARY } else { COLOR_SURFACE_1 }; + + let btn_style = |bg: &str| { + format!( + "width: 100%; padding: {p}px 0; background-color: {bg}; \ + color: {fg}; border: none; border-radius: {r}px; cursor: pointer; \ + font-size: {size}px; font-weight: {weight}; margin-bottom: {p}px;", + p = SPACE_2, + bg = bg, + fg = COLOR_TEXT_ON_CHROME, + r = RADIUS_SM, + size = FONT_SIZE_LABEL, + weight = FONT_WEIGHT_SEMIBOLD, + ) + }; + + let disabled_btn_style = format!( + "width: 100%; padding: {p}px 0; background-color: {bg}; \ + color: {fg}; border: none; border-radius: {r}px; cursor: not-allowed; \ + font-size: {size}px; font-weight: {weight}; margin-bottom: {p}px; opacity: 0.5;", + p = SPACE_2, + bg = COLOR_SURFACE_1, + fg = COLOR_TEXT_ON_CHROME_SECONDARY, + r = RADIUS_SM, + size = FONT_SIZE_LABEL, + weight = FONT_WEIGHT_SEMIBOLD, + ); + + rsx! { + div { + style: "width: {TOOL_PALETTE_WIDTH}px; background-color: {COLOR_SURFACE_1}; \ + display: flex; flex-direction: column; padding: {SPACE_2}px; \ + border-right: 1px solid {COLOR_BORDER_CHROME}; flex-shrink: 0; box-sizing: border-box;", + button { + style: btn_style(pixel_bg), + onclick: move |_| state.write().tool_mode = ToolMode::Pixel, + "Px" + // TODO(iris): Phase 3 — SVG icon when appthere_ui ships Tabler Icons + } + button { + style: btn_style(vector_bg), + onclick: move |_| state.write().tool_mode = ToolMode::Vector, + "Vc" + } + button { style: disabled_btn_style.clone(), disabled: true, "B" } + button { style: disabled_btn_style.clone(), disabled: true, "E" } + button { style: disabled_btn_style.clone(), disabled: true, "P" } + button { style: disabled_btn_style.clone(), disabled: true, "T" } + } + } +} From 6480454e15fe346a8f397af55b24bef2666e678e Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 19 May 2026 09:20:06 +0000 Subject: [PATCH 03/13] fix(iris-canvas): correct TileParams uniform buffer layout mismatch WGSL `vec3` has 16-byte alignment, which forced `_pad` to start at offset 48 and bloated the struct to 64 bytes. The Rust `[f32; 3]` counterpart has 4-byte alignment, making the Rust struct 48 bytes. wgpu validation rejected the draw call because the uploaded buffer was 48 bytes but the shader expected 64. Replace `_pad: vec3` with three separate `f32` scalars (_pad0, _pad1, _pad2). All three have align=4, so they pack immediately after opacity at offsets 36/40/44, giving a 48-byte struct on both sides. 48 is already a multiple of 16, so no struct-level padding is added. https://claude.ai/code/session_0124A4b3rVSawFEMkb2cUmcn --- crates/iris-canvas/src/shaders/normal_blend.wgsl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/iris-canvas/src/shaders/normal_blend.wgsl b/crates/iris-canvas/src/shaders/normal_blend.wgsl index b99d0e1..cc5843d 100644 --- a/crates/iris-canvas/src/shaders/normal_blend.wgsl +++ b/crates/iris-canvas/src/shaders/normal_blend.wgsl @@ -22,7 +22,9 @@ struct TileParams { corner_bl: vec2, // bottom-left in NDC corner_br: vec2, // bottom-right in NDC opacity: f32, - _pad: vec3, // 16-byte alignment + _pad0: f32, + _pad1: f32, + _pad2: f32, }; @group(0) @binding(0) var t_tile: texture_2d; From 42dfcb813dc9163dfc14a91ef47f3caba758121c Mon Sep 17 00:00:00 2001 From: Kevin Carlson Date: Tue, 19 May 2026 05:32:46 -0400 Subject: [PATCH 04/13] Added patches from Loki --- crates/patches/blitz-dom/.cargo-ok | 1 + crates/patches/blitz-dom/.cargo_vcs_info.json | 6 + crates/patches/blitz-dom/Cargo.lock | 2167 +++++++++ crates/patches/blitz-dom/Cargo.toml | 192 + crates/patches/blitz-dom/Cargo.toml.orig | 89 + crates/patches/blitz-dom/assets/default.css | 1070 +++++ .../blitz-dom/assets/moz-bullet-font.otf | Bin 0 -> 5064 bytes crates/patches/blitz-dom/src/accessibility.rs | 78 + crates/patches/blitz-dom/src/config.rs | 29 + crates/patches/blitz-dom/src/debug.rs | 139 + crates/patches/blitz-dom/src/document.rs | 1394 ++++++ crates/patches/blitz-dom/src/events/driver.rs | 128 + crates/patches/blitz-dom/src/events/ime.rs | 45 + .../patches/blitz-dom/src/events/keyboard.rs | 257 + crates/patches/blitz-dom/src/events/mod.rs | 60 + crates/patches/blitz-dom/src/events/mouse.rs | 274 ++ crates/patches/blitz-dom/src/font_metrics.rs | 159 + crates/patches/blitz-dom/src/form.rs | 463 ++ crates/patches/blitz-dom/src/html.rs | 29 + .../patches/blitz-dom/src/layout/construct.rs | 952 ++++ crates/patches/blitz-dom/src/layout/damage.rs | 386 ++ crates/patches/blitz-dom/src/layout/inline.rs | 272 ++ crates/patches/blitz-dom/src/layout/list.rs | 202 + crates/patches/blitz-dom/src/layout/mod.rs | 483 ++ .../patches/blitz-dom/src/layout/replaced.rs | 227 + crates/patches/blitz-dom/src/layout/table.rs | 335 ++ crates/patches/blitz-dom/src/lib.rs | 80 + crates/patches/blitz-dom/src/mutator.rs | 825 ++++ crates/patches/blitz-dom/src/net.rs | 347 ++ .../patches/blitz-dom/src/node/attributes.rs | 53 + crates/patches/blitz-dom/src/node/element.rs | 591 +++ crates/patches/blitz-dom/src/node/mod.rs | 13 + crates/patches/blitz-dom/src/node/node.rs | 832 ++++ .../patches/blitz-dom/src/query_selector.rs | 78 + crates/patches/blitz-dom/src/stylo.rs | 1117 +++++ .../blitz-dom/src/stylo_to_cursor_icon.rs | 48 + .../patches/blitz-dom/src/stylo_to_parley.rs | 207 + crates/patches/blitz-dom/src/traversal.rs | 238 + crates/patches/blitz-dom/src/url.rs | 53 + crates/patches/blitz-dom/src/util.rs | 139 + .../patches/blitz-shell/.cargo-checksum.json | 1 + .../patches/blitz-shell/.cargo_vcs_info.json | 6 + crates/patches/blitz-shell/Cargo.lock | 4199 +++++++++++++++++ crates/patches/blitz-shell/Cargo.toml | 116 + crates/patches/blitz-shell/Cargo.toml.orig | 56 + .../patches/blitz-shell/src/accessibility.rs | 22 + crates/patches/blitz-shell/src/application.rs | 128 + .../patches/blitz-shell/src/convert_events.rs | 603 +++ crates/patches/blitz-shell/src/event.rs | 92 + crates/patches/blitz-shell/src/lib.rs | 169 + crates/patches/blitz-shell/src/net.rs | 78 + crates/patches/blitz-shell/src/window.rs | 524 ++ crates/patches/dioxus-native-dom/.cargo-ok | 1 + .../dioxus-native-dom/.cargo_vcs_info.json | 7 + crates/patches/dioxus-native-dom/Cargo.lock | 2689 +++++++++++ crates/patches/dioxus-native-dom/Cargo.toml | 87 + .../patches/dioxus-native-dom/Cargo.toml.orig | 39 + .../dioxus-native-dom/src/dioxus_document.rs | 330 ++ .../patches/dioxus-native-dom/src/events.rs | 348 ++ crates/patches/dioxus-native-dom/src/lib.rs | 52 + .../dioxus-native-dom/src/mutation_writer.rs | 342 ++ crates/patches/fontique/.cargo-ok | 1 + crates/patches/fontique/.cargo_vcs_info.json | 6 + crates/patches/fontique/Cargo.lock | 387 ++ crates/patches/fontique/Cargo.toml | 194 + crates/patches/fontique/Cargo.toml.orig | 80 + crates/patches/fontique/LICENSE-APACHE | 201 + crates/patches/fontique/LICENSE-MIT | 25 + crates/patches/fontique/README.md | 54 + .../fontique/examples/generic_families.rs | 37 + crates/patches/fontique/src/attributes.rs | 42 + .../patches/fontique/src/backend/android.rs | 221 + .../patches/fontique/src/backend/coretext.rs | 193 + crates/patches/fontique/src/backend/dwrite.rs | 397 ++ .../fontique/src/backend/fontconfig.rs | 838 ++++ crates/patches/fontique/src/backend/mod.rs | 74 + crates/patches/fontique/src/charmap.rs | 127 + crates/patches/fontique/src/collection/mod.rs | 870 ++++ .../patches/fontique/src/collection/query.rs | 307 ++ crates/patches/fontique/src/fallback.rs | 287 ++ crates/patches/fontique/src/family.rs | 111 + crates/patches/fontique/src/family_name.rs | 119 + crates/patches/fontique/src/font.rs | 480 ++ crates/patches/fontique/src/generic.rs | 36 + .../patches/fontique/src/impl_fontconfig.rs | 159 + crates/patches/fontique/src/lib.rs | 77 + crates/patches/fontique/src/matching.rs | 464 ++ crates/patches/fontique/src/scan.rs | 304 ++ crates/patches/fontique/src/script.rs | 289 ++ crates/patches/fontique/src/source.rs | 108 + crates/patches/fontique/src/source_cache.rs | 254 + 91 files changed, 30689 insertions(+) create mode 100644 crates/patches/blitz-dom/.cargo-ok create mode 100644 crates/patches/blitz-dom/.cargo_vcs_info.json create mode 100644 crates/patches/blitz-dom/Cargo.lock create mode 100644 crates/patches/blitz-dom/Cargo.toml create mode 100644 crates/patches/blitz-dom/Cargo.toml.orig create mode 100644 crates/patches/blitz-dom/assets/default.css create mode 100644 crates/patches/blitz-dom/assets/moz-bullet-font.otf create mode 100644 crates/patches/blitz-dom/src/accessibility.rs create mode 100644 crates/patches/blitz-dom/src/config.rs create mode 100644 crates/patches/blitz-dom/src/debug.rs create mode 100644 crates/patches/blitz-dom/src/document.rs create mode 100644 crates/patches/blitz-dom/src/events/driver.rs create mode 100644 crates/patches/blitz-dom/src/events/ime.rs create mode 100644 crates/patches/blitz-dom/src/events/keyboard.rs create mode 100644 crates/patches/blitz-dom/src/events/mod.rs create mode 100644 crates/patches/blitz-dom/src/events/mouse.rs create mode 100644 crates/patches/blitz-dom/src/font_metrics.rs create mode 100644 crates/patches/blitz-dom/src/form.rs create mode 100644 crates/patches/blitz-dom/src/html.rs create mode 100644 crates/patches/blitz-dom/src/layout/construct.rs create mode 100644 crates/patches/blitz-dom/src/layout/damage.rs create mode 100644 crates/patches/blitz-dom/src/layout/inline.rs create mode 100644 crates/patches/blitz-dom/src/layout/list.rs create mode 100644 crates/patches/blitz-dom/src/layout/mod.rs create mode 100644 crates/patches/blitz-dom/src/layout/replaced.rs create mode 100644 crates/patches/blitz-dom/src/layout/table.rs create mode 100644 crates/patches/blitz-dom/src/lib.rs create mode 100644 crates/patches/blitz-dom/src/mutator.rs create mode 100644 crates/patches/blitz-dom/src/net.rs create mode 100644 crates/patches/blitz-dom/src/node/attributes.rs create mode 100644 crates/patches/blitz-dom/src/node/element.rs create mode 100644 crates/patches/blitz-dom/src/node/mod.rs create mode 100644 crates/patches/blitz-dom/src/node/node.rs create mode 100644 crates/patches/blitz-dom/src/query_selector.rs create mode 100644 crates/patches/blitz-dom/src/stylo.rs create mode 100644 crates/patches/blitz-dom/src/stylo_to_cursor_icon.rs create mode 100644 crates/patches/blitz-dom/src/stylo_to_parley.rs create mode 100644 crates/patches/blitz-dom/src/traversal.rs create mode 100644 crates/patches/blitz-dom/src/url.rs create mode 100644 crates/patches/blitz-dom/src/util.rs create mode 100644 crates/patches/blitz-shell/.cargo-checksum.json create mode 100644 crates/patches/blitz-shell/.cargo_vcs_info.json create mode 100644 crates/patches/blitz-shell/Cargo.lock create mode 100644 crates/patches/blitz-shell/Cargo.toml create mode 100644 crates/patches/blitz-shell/Cargo.toml.orig create mode 100644 crates/patches/blitz-shell/src/accessibility.rs create mode 100644 crates/patches/blitz-shell/src/application.rs create mode 100644 crates/patches/blitz-shell/src/convert_events.rs create mode 100644 crates/patches/blitz-shell/src/event.rs create mode 100644 crates/patches/blitz-shell/src/lib.rs create mode 100644 crates/patches/blitz-shell/src/net.rs create mode 100644 crates/patches/blitz-shell/src/window.rs create mode 100644 crates/patches/dioxus-native-dom/.cargo-ok create mode 100644 crates/patches/dioxus-native-dom/.cargo_vcs_info.json create mode 100644 crates/patches/dioxus-native-dom/Cargo.lock create mode 100644 crates/patches/dioxus-native-dom/Cargo.toml create mode 100644 crates/patches/dioxus-native-dom/Cargo.toml.orig create mode 100644 crates/patches/dioxus-native-dom/src/dioxus_document.rs create mode 100644 crates/patches/dioxus-native-dom/src/events.rs create mode 100644 crates/patches/dioxus-native-dom/src/lib.rs create mode 100644 crates/patches/dioxus-native-dom/src/mutation_writer.rs create mode 100644 crates/patches/fontique/.cargo-ok create mode 100644 crates/patches/fontique/.cargo_vcs_info.json create mode 100644 crates/patches/fontique/Cargo.lock create mode 100644 crates/patches/fontique/Cargo.toml create mode 100644 crates/patches/fontique/Cargo.toml.orig create mode 100644 crates/patches/fontique/LICENSE-APACHE create mode 100644 crates/patches/fontique/LICENSE-MIT create mode 100644 crates/patches/fontique/README.md create mode 100644 crates/patches/fontique/examples/generic_families.rs create mode 100644 crates/patches/fontique/src/attributes.rs create mode 100644 crates/patches/fontique/src/backend/android.rs create mode 100644 crates/patches/fontique/src/backend/coretext.rs create mode 100644 crates/patches/fontique/src/backend/dwrite.rs create mode 100644 crates/patches/fontique/src/backend/fontconfig.rs create mode 100644 crates/patches/fontique/src/backend/mod.rs create mode 100644 crates/patches/fontique/src/charmap.rs create mode 100644 crates/patches/fontique/src/collection/mod.rs create mode 100644 crates/patches/fontique/src/collection/query.rs create mode 100644 crates/patches/fontique/src/fallback.rs create mode 100644 crates/patches/fontique/src/family.rs create mode 100644 crates/patches/fontique/src/family_name.rs create mode 100644 crates/patches/fontique/src/font.rs create mode 100644 crates/patches/fontique/src/generic.rs create mode 100644 crates/patches/fontique/src/impl_fontconfig.rs create mode 100644 crates/patches/fontique/src/lib.rs create mode 100644 crates/patches/fontique/src/matching.rs create mode 100644 crates/patches/fontique/src/scan.rs create mode 100644 crates/patches/fontique/src/script.rs create mode 100644 crates/patches/fontique/src/source.rs create mode 100644 crates/patches/fontique/src/source_cache.rs diff --git a/crates/patches/blitz-dom/.cargo-ok b/crates/patches/blitz-dom/.cargo-ok new file mode 100644 index 0000000..5f8b795 --- /dev/null +++ b/crates/patches/blitz-dom/.cargo-ok @@ -0,0 +1 @@ +{"v":1} \ No newline at end of file diff --git a/crates/patches/blitz-dom/.cargo_vcs_info.json b/crates/patches/blitz-dom/.cargo_vcs_info.json new file mode 100644 index 0000000..8c97b5b --- /dev/null +++ b/crates/patches/blitz-dom/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "0a77560e59440d3c6b5f14b673b9c722a08a3d4c" + }, + "path_in_vcs": "packages/blitz-dom" +} \ No newline at end of file diff --git a/crates/patches/blitz-dom/Cargo.lock b/crates/patches/blitz-dom/Cargo.lock new file mode 100644 index 0000000..e718c15 --- /dev/null +++ b/crates/patches/blitz-dom/Cargo.lock @@ -0,0 +1,2167 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "accesskit" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "app_units" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467b60e4ee6761cd6fd4e03ea58acefc8eec0d1b1def995c1b3b783fa7be8a60" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "atomic_refcell" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +dependencies = [ + "serde", +] + +[[package]] +name = "blitz-dom" +version = "0.2.4" +dependencies = [ + "accesskit", + "app_units", + "atomic_refcell", + "bitflags", + "blitz-traits", + "color", + "cssparser", + "cursor-icon", + "debug_timer", + "euclid", + "fastrand", + "html-escape", + "image", + "keyboard-types", + "linebender_resource_handle", + "markup5ever", + "objc2", + "parley", + "percent-encoding", + "rayon", + "selectors", + "skrifa", + "slab", + "smallvec", + "stylo", + "stylo_config", + "stylo_dom", + "stylo_taffy", + "stylo_traits", + "taffy", + "tracing", + "url", + "usvg", + "woff", + "wuff", +] + +[[package]] +name = "blitz-traits" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cd87a5b7bc1bc3d546aeb28d0867ff3191e9c4e85452e1808931200a4bc49d4" +dependencies = [ + "bitflags", + "bytes", + "cursor-icon", + "http", + "keyboard-types", + "serde", + "smol_str", + "url", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bytemuck" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "color" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18ef4657441fb193b65f34dc39b3781f0dfec23d3bd94d0eeb4e88cde421edb" + +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "cssparser" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e901edd733a1472f944a45116df3f846f54d37e67e68640ac8bb69689aca2aa" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf", + "serde", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + +[[package]] +name = "debug_timer" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601b64630ed8e9306553e4b97e33516f9b4a69f520d0b25c5c7e93e5e93043d3" + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "dtoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "font-types" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a596f5713680923a2080d86de50fe472fb290693cf0f701187a1c8b36996b7" + +[[package]] +name = "font-types" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511e2c18a516c666d27867d2f9821f76e7d591f762e9fc41dd6cc5c90fe54b0b" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "fontconfig-parser" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" +dependencies = [ + "roxmltree", +] + +[[package]] +name = "fontdb" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser", +] + +[[package]] +name = "fontique" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff3336bc0b87fe42305047263fa60d2eabd650d29cbe62fdeb2a66c7a0a595f9" +dependencies = [ + "bytemuck", + "hashbrown 0.15.5", + "icu_locale_core", + "linebender_resource_handle", + "memmap2", + "objc2", + "objc2-core-foundation", + "objc2-core-text", + "objc2-foundation", + "read-fonts", + "roxmltree", + "smallvec", + "windows", + "windows-core", + "yeslogic-fontconfig-sys", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "grid" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12101ecc8225ea6d675bc70263074eab6169079621c2186fe0c66590b2df9681" + +[[package]] +name = "harfrust" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3fd23d35c2d8bcf34a1f0e9ea8c0ad263f0c8a9a47108eee23aac76e71645a" +dependencies = [ + "bitflags", + "bytemuck", + "core_maths", + "read-fonts", + "smallvec", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ae5921528335e91da1b6c695dbf1ec37df5ac13faa3f91e5640be93aa2fbefd" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_locale_data", + "icu_provider", + "potential_utf", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locale_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fdef0c124749d06a743c69e938350816554eb63ac979166590e2b4ee4252765" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_segmenter" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e185fc13b6401c138cf40db12b863b35f5edf31b88192a545857b41aeaf7d3d3" +dependencies = [ + "core_maths", + "displaydoc", + "icu_collections", + "icu_locale", + "icu_locale_core", + "icu_provider", + "icu_segmenter_data", + "potential_utf", + "utf8_iter", + "zerovec", +] + +[[package]] +name = "icu_segmenter_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5360a2fbe97f617c4f8b944356dedb36d423f7da7f13c070995cf89e59f01220" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf4f5d937a025381f5ab13624b1c5f51414bfe5c9885663226eae8d6d39560" + +[[package]] +name = "image" +version = "0.25.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "num-traits", +] + +[[package]] +name = "imagesize" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown 0.16.0", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kurbo" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" +dependencies = [ + "arrayvec", + "euclid", + "smallvec", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "linebender_resource_handle" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_size_of_derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f44db74bde26fdf427af23f1d146c211aed857c59e3be750cf2617f6b0b05c94" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "markup5ever" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "311fe69c934650f8f19652b3946075f0fc41ad8757dbb68f1ca14e7900ecc1c3" +dependencies = [ + "log", + "tendril", + "web_atoms", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memmap2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +dependencies = [ + "libc", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "objc2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ba833d4a1cb1aac330f8c973fd92b6ff1858e4aef5cdd00a255eefb28022fb5" +dependencies = [ + "bitflags", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "bitflags", + "objc2", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "parley" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26746861bb76dbc9bcd5ed1b0b55d2fedf291100961251702a031ab2abd2ce52" +dependencies = [ + "fontique", + "harfrust", + "hashbrown 0.15.5", + "linebender_resource_handle", + "skrifa", + "swash", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "serde", + "zerovec", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "read-fonts" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" +dependencies = [ + "bytemuck", + "core_maths", + "font-types 0.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustybuzz" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" +dependencies = [ + "bitflags", + "bytemuck", + "core_maths", + "log", + "smallvec", + "ttf-parser", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09975d3195f34dce9c7b381cb0f00c3c13381d4d3735c0f1a9c894b283b302ab" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "log", + "new_debug_unreachable", + "phf", + "phf_codegen", + "precomputed-hash", + "rustc-hash", + "servo_arc", + "smallvec", + "to_shmem", + "to_shmem_derive", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "servo_arc" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "204ea332803bd95a0b60388590d59cf6468ec9becf626e2451f1d26a1d972de4" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simplecss" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "skrifa" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" +dependencies = [ + "bytemuck", + "read-fonts", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallbitvec" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d31d263dd118560e1a492922182ab6ca6dc1d03a3bf54e7699993f31a4150e3f" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + +[[package]] +name = "stylo" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff45c788bcb0230aff156dce747d4d0d7f793f525764fd6690d51bbfe1f5bbd5" +dependencies = [ + "app_units", + "arrayvec", + "atomic_refcell", + "bitflags", + "byteorder", + "cssparser", + "derive_more", + "encoding_rs", + "euclid", + "icu_segmenter", + "indexmap", + "itertools", + "itoa", + "lazy_static", + "log", + "malloc_size_of_derive", + "matches", + "mime", + "new_debug_unreachable", + "num-derive", + "num-integer", + "num-traits", + "num_cpus", + "parking_lot", + "precomputed-hash", + "rayon", + "rayon-core", + "rustc-hash", + "selectors", + "serde", + "servo_arc", + "smallbitvec", + "smallvec", + "static_assertions", + "string_cache", + "stylo_atoms", + "stylo_config", + "stylo_derive", + "stylo_dom", + "stylo_malloc_size_of", + "stylo_static_prefs", + "stylo_traits", + "thin-vec", + "to_shmem", + "to_shmem_derive", + "uluru", + "url", + "void", + "walkdir", + "web_atoms", +] + +[[package]] +name = "stylo_atoms" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d6ff15e6ed626c331663555af48b8f21bc46f729f45711597143dc1bf50fb5" +dependencies = [ + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "stylo_config" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebdb6722cde5d2660928c63e07b3afbef1be8376e2b247e96e381ba5e99db33a" + +[[package]] +name = "stylo_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1724b911e0775fb9379dc629b1c3647fed991f90ddb865f74a2a26f7b030777" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "stylo_dom" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c0101ada15990fee6269257538cbcbc6f01462dc4b22d6f820edb6a4427e82" +dependencies = [ + "bitflags", + "stylo_malloc_size_of", +] + +[[package]] +name = "stylo_malloc_size_of" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8185a7a3cf0716c475ad113b494c276acf534b518dd41ee47ad5aba4af6690e" +dependencies = [ + "app_units", + "cssparser", + "euclid", + "selectors", + "servo_arc", + "smallbitvec", + "smallvec", + "string_cache", + "thin-vec", + "void", +] + +[[package]] +name = "stylo_static_prefs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca4c89da4ab6ac0beda8b03db38216967c99f1f7287a0f3b0f366b45d34ac7c4" + +[[package]] +name = "stylo_taffy" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b841aad2b770ef75dd134ba885aef0716f2ac3a83ccaf0fc31b09c8b02562e23" +dependencies = [ + "stylo", + "stylo_atoms", + "taffy", +] + +[[package]] +name = "stylo_traits" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58034d08877fb80a5496301fde9111bc57e761f4a78045222af30ce95ec150f" +dependencies = [ + "app_units", + "bitflags", + "cssparser", + "euclid", + "malloc_size_of_derive", + "selectors", + "serde", + "servo_arc", + "stylo_atoms", + "stylo_malloc_size_of", + "thin-vec", + "to_shmem", + "to_shmem_derive", + "url", +] + +[[package]] +name = "svgtypes" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" +dependencies = [ + "kurbo", + "siphasher", +] + +[[package]] +name = "swash" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" +dependencies = [ + "skrifa", + "yazi", + "zeno", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "taffy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25026fb8cc9ab51ab9fdabe5d11706796966f6d1c78e19871ef63be2b8f0644" +dependencies = [ + "arrayvec", + "grid", + "serde", + "slotmap", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-vec" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "to_shmem" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb61262d1e7e4cc777e40cb2f101d5fa51f3eeac50c3a7355b2027b9274baa35" +dependencies = [ + "cssparser", + "servo_arc", + "smallbitvec", + "smallvec", + "string_cache", + "thin-vec", +] + +[[package]] +name = "to_shmem_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba1f5563024b63bb6acb4558452d9ba737518c1d11fcc1861febe98d1e31cf4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] + +[[package]] +name = "uluru" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c8a2469e56e6e5095c82ccd3afb98dad95f7af7929aab6d8ba8d6e0f73657da" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe" + +[[package]] +name = "unicode-ccc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode-script" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "usvg" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef" +dependencies = [ + "base64", + "data-url", + "flate2", + "fontdb", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree", + "rustybuzz", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "web_atoms" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" +dependencies = [ + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "woff" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d61720725e0f4bc536c1483b2d09f62469ea9dead6b03bad70dbfea649d90e" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "wuff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a267ddde5dc265fb7176bd82ba2c2596c8345be3865f29ba314da5080e7bf1" +dependencies = [ + "arrayvec", + "brotli-decompressor", + "bytes", + "flate2", + "font-types 0.9.0", +] + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "yazi" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" + +[[package]] +name = "yeslogic-fontconfig-sys" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503a066b4c037c440169d995b869046827dbc71263f6e8f3be6d77d4f3229dbd" +dependencies = [ + "dlib", + "once_cell", + "pkg-config", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/crates/patches/blitz-dom/Cargo.toml b/crates/patches/blitz-dom/Cargo.toml new file mode 100644 index 0000000..bef4f63 --- /dev/null +++ b/crates/patches/blitz-dom/Cargo.toml @@ -0,0 +1,192 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2024" +rust-version = "1.86.0" +name = "blitz-dom" +version = "0.2.4" +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Blitz DOM implementation" +homepage = "https://github.com/dioxuslabs/blitz" +documentation = "https://docs.rs/blitz-dom" +readme = false +categories = ["gui"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dioxuslabs/blitz" +resolver = "2" + +[features] +accessibility = ["accesskit"] +autofocus = [] +default = [ + "svg", + "woff-rust", + "accessibility", + "system_fonts", + "file_input", +] +file_input = [] +incremental = [] +log_phase_times = ["debug_timer/enable"] +parallel-construct = [] +svg = ["dep:usvg"] +system_fonts = ["parley/system"] +tracing = ["dep:tracing"] +woff-c = ["dep:woff"] +woff-rust = ["dep:wuff"] + +[lib] +name = "blitz_dom" +path = "src/lib.rs" + +[dependencies.accesskit] +version = "0.17" +optional = true + +[dependencies.app_units] +version = "0.7.5" + +[dependencies.atomic_refcell] +version = "0.1.13" + +[dependencies.bitflags] +version = "2.8.0" + +[dependencies.blitz-traits] +version = "0.2.0" +default-features = false + +[dependencies.color] +version = "0.3" + +[dependencies.cssparser] +version = "0.35" + +[dependencies.cursor-icon] +version = "1" + +[dependencies.debug_timer] +version = "0.1.2" + +[dependencies.euclid] +version = "0.22" + +[dependencies.fastrand] +version = "2.3.0" + +[dependencies.html-escape] +version = "0.2.13" + +[dependencies.image] +version = "=0.25.6" +default-features = false + +[dependencies.keyboard-types] +version = "0.7" + +[dependencies.linebender_resource_handle] +version = "0.1" + +[dependencies.markup5ever] +version = "0.35" + +[dependencies.parley] +version = "0.6.0" +features = ["std"] +default-features = false + +[dependencies.percent-encoding] +version = "2.3.1" + +[dependencies.rayon] +version = "1" + +[dependencies.selectors] +version = "0.32" +package = "selectors" + +[dependencies.skrifa] +version = "0.37" +features = ["std"] +default-features = false + +[dependencies.slab] +version = "0.4.9" + +[dependencies.smallvec] +version = "1" + +[dependencies.style] +version = "0.8" +package = "stylo" + +[dependencies.style_config] +version = "0.8" +package = "stylo_config" + +[dependencies.style_dom] +version = "0.8" +package = "stylo_dom" + +[dependencies.style_traits] +version = "0.8" +package = "stylo_traits" + +[dependencies.stylo_taffy] +version = "0.2.0" +features = ["default"] +default-features = false + +[dependencies.taffy] +version = "0.9" +features = [ + "std", + "flexbox", + "grid", + "block_layout", + "content_size", + "calc", +] +default-features = false + +[dependencies.tracing] +version = "0.1.40" +optional = true + +[dependencies.url] +version = "2.5.0" + +[dependencies.usvg] +version = "0.45.1" +optional = true + +[dependencies.woff] +version = "0.6" +features = [ + "version1", + "version2", +] +optional = true +default-features = false + +[dependencies.wuff] +version = "0.2" +optional = true + +[target.'cfg(any(target_vendor = "apple"))'.dependencies.objc2] +version = "0.6" +features = ["disable-encoding-assertions"] diff --git a/crates/patches/blitz-dom/Cargo.toml.orig b/crates/patches/blitz-dom/Cargo.toml.orig new file mode 100644 index 0000000..09df75b --- /dev/null +++ b/crates/patches/blitz-dom/Cargo.toml.orig @@ -0,0 +1,89 @@ +[package] +name = "blitz-dom" +description = "Blitz DOM implementation" +documentation = "https://docs.rs/blitz-dom" +version = "0.2.4" +license.workspace = true +homepage.workspace = true +repository.workspace = true +categories.workspace = true +edition.workspace = true +rust-version.workspace = true + +[features] +default = [ + "svg", + "woff-rust", + "accessibility", + "system_fonts", + "file_input", +] +tracing = ["dep:tracing"] +svg = ["dep:usvg"] +# WOFF decoding using the "woff" crate which binds to C libraries +woff-c = ["dep:woff"] +# WOFF decoding using the "wuff" crate which is pure Rust +woff-rust = ["dep:wuff"] +accessibility = ["accesskit"] +system_fonts = ["parley/system"] +autofocus = [] +file_input = [] +incremental = [] +parallel-construct = [] +log_phase_times = ["debug_timer/enable"] + +[dependencies] +# Blitz dependencies +blitz-traits = { workspace = true } +stylo_taffy = { workspace = true, features = ["default"] } +debug_timer = { workspace = true } + +# Servo dependencies +style = { workspace = true } +selectors = { workspace = true } +cssparser = { workspace = true } +style_config = { workspace = true } +style_traits = { workspace = true } +style_dom = { workspace = true } +app_units = { workspace = true } +euclid = { workspace = true } +atomic_refcell = { workspace = true } +markup5ever = { workspace = true } +smallvec = { workspace = true } + +# DioxusLabs dependencies +taffy = { workspace = true } + +# Linebender/Fontations dependencies +accesskit = { workspace = true, optional = true } +parley = { workspace = true } +skrifa = { workspace = true } +linebender_resource_handle = { workspace = true } +color = { workspace = true } + +# Other dependencies +slab = { workspace = true } +bitflags = { workspace = true } +tracing = { workspace = true, optional = true } +fastrand = { workspace = true } +rayon = { workspace = true } + +# Media & Decoding +image = { workspace = true } +usvg = { workspace = true, optional = true } +woff = { workspace = true, optional = true, features = ["version1", "version2"] } +wuff = { workspace = true, optional = true } +html-escape = { workspace = true } +percent-encoding = { workspace = true } + +# IO & Networking +url = { workspace = true } + +# Input +keyboard-types = { workspace = true } +cursor-icon = { workspace = true } + +# HACK: Blitz doesn't need to depend on objc2 directly. But this feature flag is necessary +# to prevent debug builds from panicking. +[target.'cfg(any(target_vendor = "apple"))'.dependencies] +objc2 = { version = "0.6", features = ["disable-encoding-assertions"] } diff --git a/crates/patches/blitz-dom/assets/default.css b/crates/patches/blitz-dom/assets/default.css new file mode 100644 index 0000000..28e825e --- /dev/null +++ b/crates/patches/blitz-dom/assets/default.css @@ -0,0 +1,1070 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +@namespace url(http://www.w3.org/1999/xhtml); +/* set default namespace to HTML */ +@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul); + +@font-face { + font-family: -moz-bullet-font; + src: url("data:font/woff2;base64,d09GMgABAAAAAARYAAwAAAAACqAAAAQFAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cBmAAgwIRCAqKDIcYATYCJAMsCxgABCAFg2AHIBtDCFGUrM0MyM/DGJyndUclpZwnU8QPQ6wsFOHO+/yHNvV9IEqSQgsVJW2p+uZkohKbVExPEz/JUW7zk6rzYH9723UJ/4DzBII8CSzwgFMOOE4KW2rjAmh4qQWSiid60f7Y9FsXScfUpeluagFqTTQYyoQaQSubXil0lHRsBehAI9KofG/6ogF9/Hl6lBd920LmeTxj8JXBfFWKwYAY3QsAAXD17ZAB4M6Ocv/nsZlkaTl0gLipewIQEMB2d9lKDAT1ZjP/F7jmWsQ3wn8AZvZFgIIC7ESh4AP1iFb4nPnfWyJgcQArpUWqW9W96j71kHr/L9a/dNRbj+8/ujXLWCMMFYVYiXoEaZQ4YOC/E7Dkz3JEjaokxAP6i3hIUjv9fwYyE6I3yIozKkaGN63fP36aeLJmxlRZwZiFziPrMVvOlnCF98SQJfGO/Xllv/FnWAcEjrMqaMCPwVmktCDO5zzxcXqeKS+QFxYnvJLFVzKZAFcKnlZRwHEPVM3mXxNt2gdZEpkKaIAG9gbgDTU5SOYDcmX7Rr61evEA1U+1/3SMb6FFtUqh55nYleE95j2zPNxzdlnGoR5xu/PxQKzb7bFaFLvl79Z54Lx9OH+g0/PPYlcsNo/nwP2V2vsHUHsV4KqEsd+e2r6Fu2v7abkfvsb65b41uwvRvqewH25kTntqolbYsEr5DAqrX97a0jrBLjFRExVHR2dH1Za6unyZfCVZHqQP0BtYjuUYlg9J6SurcrTEiOr26m5xcuTW4Sp3ljkUYWJ9+/iVmzbzPpcuXnGeqU3U7IKjz/qeKSSCltyhuSoxkqqTZX+DXt/OMmAikC8SzVD0jg3dbhIE0eUqc04UFFrxCSXzFxgHclzRMPe0ocOjiKRoSZISE0OtpkBjECdxkkRM1KiaJV0ed0V5umBP1wyUPL2ZBGLSDh5itIHahHRF0CY5nZMGib6T3cOmDvcTSZKuPiFJFpPRGNTIOq7jl5OjDiGIoo6qEE0QtfQJ3VYUD2RZvbm5uWWCWOgR4HXAk5GxLEO0izhLdvPTfpTV3xeOnOfT96uR53CdPrPq+P9HZvzO4QCMmDr7lTcNZorT6iMOYgI+IxClMzeCspeoLt5ABGSpta6gRZmQSnzk9e9jmOAYKC7RsyGMYaB6MpbNKMiRq2U6vI0yPZuTMiODFytMrGEBi7pjGgkAMoaNLGOFSoYceaZMx1+XTC/UNpmRzY1nmwT7AIcK+fK5lYNjz893lwMTuXlD2AKl8Md+24AxitRaLH/MUMqd9z862owy/bZTuZUqs1iRQop0KdLgZwPc9JS0lprnkef1gitBCRhjgV+vjGK8BfIV8CrlVghj1vIyZfyC/AJvqbsQYAEA/v+IAQA="); +} + +/* bidi */ + +:-moz-has-dir-attr { + unicode-bidi: isolate; +} + +:-moz-dir-attr-rtl { + direction: rtl; +} + +:-moz-dir-attr-ltr { + direction: ltr; +} + +:-moz-dir-attr-like-auto:dir(ltr) { + direction: ltr; +} + +:-moz-dir-attr-like-auto:dir(rtl) { + direction: rtl; +} + +[popover]:not(:popover-open):not(dialog[open]) { + display: none; +} + +a { + color: rgb(0, 0, 238); + text-decoration: underline; +} + +/* https://html.spec.whatwg.org/#bidi-rendering */ +input[type=tel]:dir(ltr) { + direction: ltr; +} + +input { + display: inline-block; +} + +input[type="checkbox"] { + width: 14px; + height: 14px; + margin: 3px 3px 3px 4px; +} + +input[type="radio"] { + width: 14px; + height: 14px; + border-radius: 14px; + border: none; + margin: 3px 3px 3px 4px; +} + +input, +textarea { + border: 1px solid #999; + padding: 2px; + background-color: white; +} + +input:focus, +textarea:focus { + outline: 2px #4D90FE; +} + +button, +input[type="submit"], +input[type="reset"], +input[type="button"] { + border: 1px solid #999; + border-radius: 1px; + padding: 1px 6px; + color: black; + background-color: #EFEFEF; +} + +input[type="file"] { + border: none; + padding: 0; + background-color: transparent; +} + +/* To ensure http://www.w3.org/TR/REC-html40/struct/dirlang.html#style-bidi: + * + * "When a block element that does not have a dir attribute is transformed to + * the style of an inline element by a style sheet, the resulting presentation + * should be equivalent, in terms of bidirectional formatting, to the + * formatting obtained by explicitly adding a dir attribute (assigned the + * inherited value) to the transformed element." + * + * and the rules in http://dev.w3.org/html5/spec/rendering.html#rendering + */ + +address, +article, +aside, +blockquote, +body, +caption, +center, +col, +colgroup, +dd, +dir, +div, +dl, +dt, +fieldset, +figcaption, +figure, +footer, +form, +h1, +h2, +h3, +h4, +h5, +h6, +header, +hgroup, +hr, +html, +legend, +li, +listing, +main, +marquee, +menu, +nav, +noframes, +ol, +p, +plaintext, +pre, +search, +section, +summary, +table, +tbody, +td, +tfoot, +th, +thead, +tr, +ul, +xmp { + unicode-bidi: isolate; +} + +bdi, +output { + unicode-bidi: isolate; +} + +/* We need the "bdo:-moz-has-dir-attr" bit because "bdo" has lower + specificity than the ":-moz-has-dir-attr" selector above. */ +bdo, +bdo:-moz-has-dir-attr { + unicode-bidi: isolate-override; +} + +textarea:-moz-dir-attr-like-auto, +pre:-moz-dir-attr-like-auto { + unicode-bidi: plaintext; +} + +/* blocks */ + +article, +aside, +details, +div, +dt, +figcaption, +footer, +form, +header, +hgroup, +html, +main, +nav, +search, +section, +summary { + display: block; +} + +body { + display: block; + margin: 8px; +} + +p, +dl, +multicol { + display: block; + margin-block-start: 1em; + margin-block-end: 1em; +} + +dd { + display: block; + margin-inline-start: 40px; +} + +blockquote, +figure { + display: block; + margin-block-start: 1em; + margin-block-end: 1em; + margin-inline-start: 40px; + margin-inline-end: 40px; +} + +address { + display: block; + font-style: italic; +} + +center { + display: block; + text-align: -moz-center; +} + +h1 { + display: block; + font-size: 2em; + font-weight: bold; + margin-block-start: .67em; + margin-block-end: .67em; +} + +h2 { + display: block; + font-size: 1.5em; + font-weight: bold; + margin-block-start: .83em; + margin-block-end: .83em; +} + +h3 { + display: block; + font-size: 1.17em; + font-weight: bold; + margin-block-start: 1em; + margin-block-end: 1em; +} + +h4 { + display: block; + font-size: 1.00em; + font-weight: bold; + margin-block-start: 1.33em; + margin-block-end: 1.33em; +} + +h5 { + display: block; + font-size: 0.83em; + font-weight: bold; + margin-block-start: 1.67em; + margin-block-end: 1.67em; +} + +h6 { + display: block; + font-size: 0.67em; + font-weight: bold; + margin-block-start: 2.33em; + margin-block-end: 2.33em; +} + +listing { + display: block; + font-family: -moz-fixed; + font-size: medium; + white-space: pre; + margin-block-start: 1em; + margin-block-end: 1em; +} + +xmp, +pre, +plaintext { + display: block; + font-family: -moz-fixed; + white-space: pre; + margin-block-start: 1em; + margin-block-end: 1em; +} + +/* tables */ + +table { + display: table; + border-spacing: 2px; + border-collapse: separate; + /* XXXldb do we want this if we're border-collapse:collapse ? */ + box-sizing: border-box; + text-indent: 0; +} + +table[align="left"] { + float: left; +} + +table[align="right"] { + float: right; + text-align: start; +} + + +/* border collapse rules */ + +/* Set hidden if we have 'frame' or 'rules' attribute. + Set it on all sides when we do so there's more consistency + in what authors should expect */ + +/* Put this first so 'border' and 'frame' rules can override it. */ +table[rules] { + border-width: thin; + border-style: hidden; +} + +/* 'border' before 'frame' so 'frame' overrides + A border with a given value should, of course, pass that value + as the border-width in pixels -> attr mapping */ + +/* :-moz-table-border-nonzero is like [border]:not([border="0"]) except it + also checks for other zero-like values according to HTML attribute + parsing rules */ +table:-moz-table-border-nonzero { + border-width: thin; + border-style: outset; +} + +table[frame] { + border: thin hidden; +} + +/* specificity must beat table:-moz-table-border-nonzero rule above */ +table[frame="void"] { + border-style: hidden; +} + +table[frame="above"] { + border-style: outset hidden hidden hidden; +} + +table[frame="below"] { + border-style: hidden hidden outset hidden; +} + +table[frame="lhs"] { + border-style: hidden hidden hidden outset; +} + +table[frame="rhs"] { + border-style: hidden outset hidden hidden; +} + +table[frame="hsides"] { + border-style: outset hidden; +} + +table[frame="vsides"] { + border-style: hidden outset; +} + +table[frame="box"], +table[frame="border"] { + border-style: outset; +} + + +/* Internal Table Borders */ + +/* 'border' cell borders first */ + +table:-moz-table-border-nonzero>*>tr>td, +table:-moz-table-border-nonzero>*>tr>th, +table:-moz-table-border-nonzero>*>td, +table:-moz-table-border-nonzero>*>th, +table:-moz-table-border-nonzero>td, +table:-moz-table-border-nonzero>th { + border-width: thin; + border-style: inset; +} + +/* collapse only if rules are really specified */ +table[rules]:not([rules="none"], [rules=""]) { + border-collapse: collapse; +} + +/* only specified rules override 'border' settings + (increased specificity to achieve this) */ +table[rules]:not([rules=""])>tr>td, +table[rules]:not([rules=""])>*>tr>td, +table[rules]:not([rules=""])>tr>th, +table[rules]:not([rules=""])>*>tr>th, +table[rules]:not([rules=""])>td, +table[rules]:not([rules=""])>th { + border-width: thin; + border-style: none; +} + + +table[rules][rules="none"]>tr>td, +table[rules][rules="none"]>*>tr>td, +table[rules][rules="none"]>tr>th, +table[rules][rules="none"]>*>tr>th, +table[rules][rules="none"]>td, +table[rules][rules="none"]>th { + border-width: thin; + border-style: none; +} + +table[rules][rules="all"]>tr>td, +table[rules][rules="all"]>*>tr>td, +table[rules][rules="all"]>tr>th, +table[rules][rules="all"]>*>tr>th, +table[rules][rules="all"]>td, +table[rules][rules="all"]>th { + border-width: thin; + border-style: solid; +} + +table[rules][rules="rows"]>tr, +table[rules][rules="rows"]>*>tr { + border-block-start-width: thin; + border-block-end-width: thin; + border-block-start-style: solid; + border-block-end-style: solid; +} + + +table[rules][rules="cols"]>tr>td, +table[rules][rules="cols"]>*>tr>td, +table[rules][rules="cols"]>tr>th, +table[rules][rules="cols"]>*>tr>th { + border-inline-start-width: thin; + border-inline-end-width: thin; + border-inline-start-style: solid; + border-inline-end-style: solid; +} + +table[rules][rules="groups"]>colgroup { + border-inline-start-width: thin; + border-inline-end-width: thin; + border-inline-start-style: solid; + border-inline-end-style: solid; +} + +table[rules][rules="groups"]>tfoot, +table[rules][rules="groups"]>thead, +table[rules][rules="groups"]>tbody { + border-block-start-width: thin; + border-block-end-width: thin; + border-block-start-style: solid; + border-block-end-style: solid; +} + + +/* caption inherits from table not table-outer */ +caption { + display: table-caption; + text-align: center; +} + +table[align="center"]>caption { + margin-inline-start: auto; + margin-inline-end: auto; +} + +table[align="center"]>caption[align="left"]:dir(ltr) { + margin-inline-end: 0; +} + +table[align="center"]>caption[align="left"]:dir(rtl) { + margin-inline-start: 0; +} + +table[align="center"]>caption[align="right"]:dir(ltr) { + margin-inline-start: 0; +} + +table[align="center"]>caption[align="right"]:dir(rtl) { + margin-inline-end: 0; +} + +tr { + display: table-row; + vertical-align: inherit; +} + +col { + display: table-column; +} + +colgroup { + display: table-column-group; +} + +tbody { + display: table-row-group; + vertical-align: middle; +} + +thead { + display: table-header-group; + vertical-align: middle; +} + +tfoot { + display: table-footer-group; + vertical-align: middle; +} + +/* for XHTML tables without tbody */ +table>tr { + vertical-align: middle; +} + +td { + display: table-cell; + vertical-align: inherit; + text-align: unset; + padding: 1px; +} + +th { + display: table-cell; + vertical-align: inherit; + font-weight: bold; + padding: 1px; + text-align: -moz-center-or-inherit; +} + +:is(tr, tbody, thead, tfoot, table)>form:-moz-is-html { + /* Important: don't show these forms in HTML */ + display: none !important; +} + +table[bordercolor]>tbody, +table[bordercolor]>thead, +table[bordercolor]>tfoot, +table[bordercolor]>col, +table[bordercolor]>colgroup, +table[bordercolor]>tr, +table[bordercolor]>*>tr, +table[bordercolor]>tr>td, +table[bordercolor]>*>tr>td, +table[bordercolor]>tr>th, +table[bordercolor]>*>tr>th { + border-color: inherit; +} + +/* inlines */ + +q:before { + content: open-quote; +} + +q:after { + content: close-quote; +} + +b, +strong { + font-weight: bolder; +} + +i, +cite, +em, +var, +dfn { + font-style: italic; +} + +tt, +code, +kbd, +samp { + font-family: -moz-fixed; +} + +u, +ins { + text-decoration: underline; +} + +s, +strike, +del { + text-decoration: line-through; +} + +big { + font-size: larger; +} + +small { + font-size: smaller; +} + +sub { + vertical-align: sub; + font-size: smaller; +} + +sup { + vertical-align: super; + font-size: smaller; +} + +nobr { + white-space: nowrap; +} + +mark { + background: Mark; + color: MarkText; +} + +/* titles */ +abbr[title], +acronym[title] { + text-decoration: dotted underline; +} + +/* lists */ + +ul, +menu, +dir { + display: block; + list-style-type: disc; + margin-block-start: 1em; + margin-block-end: 1em; + padding-inline-start: 40px; +} + +ul, +ol, +menu { + counter-reset: list-item; +} + +ol { + display: block; + list-style-type: decimal; + margin-block-start: 1em; + margin-block-end: 1em; + padding-inline-start: 40px; +} + +li { + display: list-item; + text-align: match-parent; +} + +/* nested lists have no top/bottom margins */ +:is(ul, ol, dir, menu, dl) ul, +:is(ul, ol, dir, menu, dl) ol, +:is(ul, ol, dir, menu, dl) dir, +:is(ul, ol, dir, menu, dl) menu, +:is(ul, ol, dir, menu, dl) dl { + margin-block-start: 0; + margin-block-end: 0; +} + +/* 2 deep unordered lists use a circle */ +:is(ol, ul, menu, dir) ul, +:is(ol, ul, menu, dir) menu, +:is(ol, ul, menu, dir) dir { + list-style-type: circle; +} + +/* 3 deep (or more) unordered lists use a square */ +:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) ul, +:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) menu, +:is(ol, ul, menu, dir) :is(ol, ul, menu, dir) dir { + list-style-type: square; +} + + +/* leafs */ + +/*
noshade and color attributes are handled completely by + * HTMLHRElement::MapAttributesIntoRule. + * https://html.spec.whatwg.org/#the-hr-element-2 + */ +hr { + color: gray; + border-width: 1px; + border-style: inset; + margin-block-start: 0.5em; + margin-block-end: 0.5em; + margin-inline-start: auto; + margin-inline-end: auto; + overflow: hidden; + + /* FIXME: This is not really per spec */ + display: block; +} + +hr[size="1"] { + border-style: solid none none none; +} + +/* Note that we only intend for the alt content to show up if the image is + * broken. But non-broken images/inputs will have a replaced box, and thus we + * won't we don't generate the pseudo-element anyways. This prevents + * unnecessary reframing when images become broken / non-broken. */ +input[type=image]::before, +img::before { + content: -moz-alt-content !important; + unicode-bidi: isolate; +} + +img[usemap], +object[usemap] { + color: blue; +} + +frameset { + display: block ! important; + overflow: clip; + position: static ! important; + float: none ! important; + border: none ! important; +} + +frame { + border-radius: 0 ! important; +} + +iframe { + border: 2px inset; +} + +spacer { + position: static ! important; + float: none ! important; +} + +canvas { + user-select: none; +} + +iframe:focus-visible, +body:focus-visible, +html:focus-visible { + /* These elements historically don't show outlines when focused by default. + * We could consider changing that if needed. */ + outline-style: none; +} + +/* hidden elements: https://html.spec.whatwg.org/#hidden-elements + * + * Exceptions: + * + * * area declaration needs to be !important, see below / bug 135040. That's + * hacky and broken. + * + * * [hidden] is implemented as a presentation attribute to avoid a global + * selector in a UA sheet. + */ +base, +basefont, +datalist, +head, +link, +meta, +noembed, +noframes, +param, +rp, +script, +style, +template, +title { + display: none; +} + +area { + /* Don't give it frames other than its imageframe */ + display: none ! important; +} + +iframe:fullscreen { + /* iframes in full-screen mode don't show a border. */ + border: none !important; + padding: unset !important; +} + +/* Details and summary + * https://html.spec.whatwg.org/#the-details-and-summary-elements + * + * Note that these rules need to be duplicated in details.css for the anonymous + * summary, which wouldn't match otherwise. + * + * The spec here says something different, see + * https://github.com/whatwg/html/issues/8610 + */ +details>summary:first-of-type { + display: list-item; + counter-increment: list-item 0; + list-style: disclosure-closed inside; +} + +details[open]>summary:first-of-type { + list-style-type: disclosure-open; +} + +/* media elements */ +video { + object-fit: contain; +} + +video>img:-moz-native-anonymous { + /* Video poster images should render with the video element's "object-fit" & + "object-position" properties */ + object-fit: inherit !important; + object-position: inherit !important; +} + +audio:not([controls]) { + display: none !important; +} + +audio[controls] { + /* This ensures that intrinsic sizing can reliably shrinkwrap our + controls (which are also always horizontal) and produce a + reasonable intrinsic size from them. */ + writing-mode: horizontal-tb !important; +} + +*|*::-moz-html-canvas-content { + display: block !important; + /* we want to be an absolute and fixed container */ + transform: translate(0) !important; +} + +video>.caption-box { + width: 100%; + height: 100%; + position: relative; +} + +/** + * The pseudo element won't inherit CSS styles from its direct parent, `::cue` + * would actually inherit styles from video because it's video's pseudo element. + * Therefore, we have to explicitly set some styles which are already defined + * in its parent element in vtt.jsm. + */ +::cue { + color: rgba(255, 255, 255, 1); + white-space: pre-line; + background-color: rgba(0, 0, 0, 0.8); + font: 10px sans-serif; + overflow-wrap: break-word; + /* TODO : enable unicode-bidi, right now enable it would cause incorrect + display direction, maybe related with bug 1558431. */ +} + +/* element styles */ + +dialog { + position: absolute; + display: block; + inset-inline-start: 0; + inset-inline-end: 0; + margin: auto; + border-width: initial; + border-style: solid; + border-color: initial; + border-image: initial; + padding: 1em; + background-color: Canvas; + color: CanvasText; + width: -moz-fit-content; + height: -moz-fit-content; +} + +dialog:not([open]) { + display: none; +} + +dialog:modal { + -moz-top-layer: top !important; + position: fixed; + overflow: auto; + visibility: visible; + inset-block-start: 0; + inset-block-end: 0; + max-width: calc(100% - 6px - 2em); + max-height: calc(100% - 6px - 2em); +} + +/* https://html.spec.whatwg.org/#flow-content-3 */ +dialog::backdrop { + background: rgba(0, 0, 0, 0.1); +} + +marquee { + inline-size: -moz-available; + display: inline-block; + vertical-align: text-bottom; + text-align: start; +} + +marquee:is([direction="up"], [direction="down"]) { + block-size: 200px; +} + +/* Ruby */ + +ruby { + display: ruby; +} + +rb { + display: ruby-base; + white-space: nowrap; +} + +rt { + display: ruby-text; +} + +rtc { + display: ruby-text-container; +} + +rtc, +rt { + white-space: nowrap; + font-size: 50%; + -moz-min-font-size-ratio: 50%; + line-height: 1; +} + +@media not (-moz-platform: windows) { + + rtc, + rt { + /* The widely-used Windows font Meiryo doesn't work fine with this + * setting, so disable this on Windows. We should re-enable it once + * Microsoft fixes this issue. See bug 1164279. */ + font-variant-east-asian: ruby; + } +} + +rtc, +rt { + text-emphasis: none; +} + +rtc:lang(zh), +rt:lang(zh) { + ruby-align: center; +} + +rtc:lang(zh-TW), +rt:lang(zh-TW) { + font-size: 30%; + /* bopomofo */ + -moz-min-font-size-ratio: 30%; +} + +rtc>rt { + font-size: unset; +} + +ruby, +rb, +rt, +rtc { + unicode-bidi: isolate; +} + +/* Shadow DOM v1 + * https://drafts.csswg.org/css-scoping/#slots-in-shadow-tree */ +slot { + display: contents; +} + +/* Un-invert images and videos for users using inverted colors. + * "User agents must add the following rule to their UA style sheet" + * https://www.w3.org/TR/mediaqueries-5/#inverted + */ +@media (inverted-colors) { + + img:not(picture > img), + picture, + video { + filter: invert(100%); + } +} + +/* Hide noscript elements if scripting is enabled */ +@media (scripting) { + noscript { + display: none !important; + } +} + +@media print { + + input, + textarea, + select, + button, + details { + -moz-user-input: none !important; + pointer-events: none !important; + } +} + +/* Popover UA style, https://html.spec.whatwg.org/#flow-content-3 */ +/* stylelint-disable-next-line media-query-no-invalid */ +@media (-moz-bool-pref: "dom.element.popover.enabled") { + [popover]:not(:popover-open):not(dialog[open]) { + display: none; + } + + dialog:popover-open { + display: block; + } + + [popover] { + position: fixed; + inset: 0; + width: fit-content; + height: fit-content; + margin: auto; + border: solid; + padding: 0.25em; + overflow: auto; + color: CanvasText; + background-color: Canvas; + } + + :popover-open { + -moz-top-layer: top; + } + + :popover-open::backdrop { + position: fixed; + inset: 0; + pointer-events: none !important; + background-color: transparent; + } +} diff --git a/crates/patches/blitz-dom/assets/moz-bullet-font.otf b/crates/patches/blitz-dom/assets/moz-bullet-font.otf new file mode 100644 index 0000000000000000000000000000000000000000..a6f7667af48bcebf5a5e14c650f2836273bb3271 GIT binary patch literal 5064 zcmc&&TWnlc72S6p_H}KKQt`eh>noDj$46k@!y)TJcncs#dt9%}ipahqd-O*B-Y8 zi4Vj$bM8L-?7jBm?0wFi965IEh&0NiL}lN>&d&7m)rA*C;xUm#wzKot;pJaF`w5ZT zCPgIm)kh9>N*gG-tq;Q;N1nWY|Jkv{*G0TE=1+ZhFgx;#&8k{^g@!Nji_>og^F`k$U9XB1XY|%+WE>ryL!Jhd*{SHGk)5AG&{c zbb~Z|P1s#8)&Ncu>{&Vj`J|(xl9JClItKcij*iRil6Q0+_+>}?(0$d>4RWWfONUIz z0RDPpT%==SV4w%jE=+rMAuFSp_Vi8+WI-I3VL2`Rs*ptzb|@bnKHWbskWGgm|CMkz zERM<;u!m&`$nCOM_K9@&jE?mW52f4pVzLwP#79~`@zK`BIY*EzA{~Q?qo4+45P^=u z_z;$|<74Tg*@3~{(H=~hZ~INT9r->p2VP2I@-&{UsDP-}X0xQzpK2?${j%-XZEqN@ z6xrroQl4ktGk^W#U#@)X%GX7%>~@%d(NCR@^={^)B*CGvtxwnkTMX-5&Gi36+SdKw z*yax4gN*J-h2=6ov6y(C*W$J}+Z;^&)y6+Ey zEuyLZ%%y6v`dU0Czi&yQrBm|fTT{}IN*r&MM#A{gf_6*EZuzu4AYYV+<#Fkn80z1L zk9|DyX!}DCK5zh&{SS6LWFLq0ad7|eNYBvI+Eu*+-y7*`--k-x*(hPbikJ5;z}~nw z>&m-^iHzcQTgp=NBzc)>NCmBm#TZK zFV!bDd-<;`ajm+i@>tSHOD3bks*%=G*@#~%uNi3|H_0JJX0lWc)`B%-Hk1#Rxu$$f zO(m0AJ7=}cI=O_bq28uWQ>i?$GNJIsyh%=sQf~s-p9m&^3<1Sb=9DpSmrBN54WSgz z{9|i+HPa0dPGP=AQGwJ#Kv-u5atutNmBLCB@zu9oT!H6)t?R8ca1}C|28N698LC=X z3zW~15hE5PttNGv$|gW;<=0PKtF%=6lN*1i;IBUMeC3to#%#TjcT43;!pMvC@rhFT zbtCsNtj0_RZ1ZixKat6N!N|SvFj1MSz6`xOBd6&#q^MQe_`I$g^HYlkP*tlqJ|X-> zbr41?7wT1SBLOAKyWujSsAqC8%_X`IJ!7y$_kUguk~4M2+{|Qx3&t4AZgMabx`C~n zaWu=syw4@2us$=V63Wf1RDKRm$k-7`RtKA+m|U5K6+CBE-k;9L9UdHjrJLL#SXGDo zvr|}AlWr)%qLS)eNX>z}&470>4~&^y&Y0`;K!<9nJT-01Kh<{V4(zaGwzWaQHARL; zAR+172iOF2F_rUv{v6zclq>O@bQ?7_J2g8EkE+NhMyTgd5kj*f6owoYpyvnY3uoiH zrVh`~;LM{0Lhy?Kr&eBh`GS3_Kl9eAV*15t$VF%xAuj+S>JYZM%9|qidSa@Ou0RMYQ5x12%z?^4bSpF&77msQ zg#~3h30qtmO+*zknWZJ95x`4^xz%`=^?0Sv9y#0ou|ODYVZN4Yy;cWQp4p`XMTcNx z#;8C%HsK?Hkk7&jj6)O_Z4z0YOrReu1{Z^isBx_h1`etlwV-nbZZ{k&b2VH)znWil zjT>$*Qb@~`M_Gi`Hn+_Us}ruFhJD&XJuipjb#4N;mknjJq{oDAl)1rB;7_iYvrmkf zOs?o_yTBlulrgdex7=nXZGCyHG#&|*v8@(1o`0?w&lLcRv~mP2@UA;q*AT$;pREhQ z6-YZBeH{23@q8}(+J(WY@xCTKnLTPCpPpsGxnI|}dW2FZEb9Dt2i*7Bi4!hm8 zzp z_rFE5K9ffXm~j?zfe$F zWSkUsPq8g;3nW|(rPW3Vhe(vf76X|Z&CD}Cmjh_2z=z*0oVTij%tI$c#z6p`fG;da zC2+%pPQnECh;IeD5&i|d3lW~Xi0aZd24G(Bv;q{_o2!eEA!kzjy6#as5qt<;fqcgR|rRt|E7l dV?W*x`M*^%hVL2gEx8q6&wI TreeUpdate { + let mut nodes = std::collections::HashMap::new(); + let mut window = AccessKitNode::new(Role::Window); + + self.visit(|node_id, node| { + let parent = node + .parent + .and_then(|parent_id| nodes.get_mut(&parent_id)) + .map(|(_, parent)| parent) + .unwrap_or(&mut window); + let (id, builder) = self.build_accessibility_node(node, parent); + + nodes.insert(node_id, (id, builder)); + }); + + let mut nodes: Vec<_> = nodes + .into_iter() + .map(|(_, (id, node))| (id, node)) + .collect(); + nodes.push((NodeId(u64::MAX), window)); + + let tree = Tree::new(NodeId(u64::MAX)); + TreeUpdate { + nodes, + tree: Some(tree), + focus: NodeId(self.focus_node_id.map(|id| id as u64).unwrap_or(u64::MAX)), + } + } + + fn build_accessibility_node( + &self, + node: &BlitzDomNode, + parent: &mut AccessKitNode, + ) -> (NodeId, AccessKitNode) { + let id = NodeId(node.id as u64); + + let mut builder = AccessKitNode::default(); + if node.id == 0 { + builder.set_role(Role::Window) + } else if let Some(element_data) = node.element_data() { + let name = element_data.name.local.to_string(); + + // TODO match more roles + let role = match &*name { + "button" => Role::Button, + "div" => Role::GenericContainer, + "header" => Role::Header, + "h1" | "h2" | "h3" | "h4" | "h5" | "h6" => Role::Heading, + "p" => Role::Paragraph, + "section" => Role::Section, + "input" => { + let ty = element_data.attr(local_name!("type")).unwrap_or("text"); + match ty { + "number" => Role::NumberInput, + "checkbox" => Role::CheckBox, + _ => Role::TextInput, + } + } + _ => Role::Unknown, + }; + + builder.set_role(role); + builder.set_html_tag(name); + } else if node.is_text_node() { + builder.set_role(Role::TextRun); + builder.set_value(node.text_content()); + parent.push_labelled_by(id) + } + + parent.push_child(id); + + (id, builder) + } +} diff --git a/crates/patches/blitz-dom/src/config.rs b/crates/patches/blitz-dom/src/config.rs new file mode 100644 index 0000000..545f382 --- /dev/null +++ b/crates/patches/blitz-dom/src/config.rs @@ -0,0 +1,29 @@ +use crate::{HtmlParserProvider, net::Resource}; +use blitz_traits::{ + navigation::NavigationProvider, + net::NetProvider, + shell::{ShellProvider, Viewport}, +}; +use parley::FontContext; +use std::sync::Arc; + +/// Options used when constructing a [`BaseDocument`](crate::BaseDocument) +#[derive(Default)] +pub struct DocumentConfig { + /// The initial `Viewport` + pub viewport: Option, + /// The base url which relative URLs are resolved against + pub base_url: Option, + /// User Agent stylesheets + pub ua_stylesheets: Option>, + /// Net provider to handle network requests for resources + pub net_provider: Option>>, + /// Navigation provider to handle link clicks and form submissions + pub navigation_provider: Option>, + /// Shell provider to redraw requests, clipboard, etc + pub shell_provider: Option>, + /// HTML parser provider. Used to parse HTML for setInnerHTML + pub html_parser_provider: Option>, + /// Parley `FontContext` + pub font_ctx: Option, +} diff --git a/crates/patches/blitz-dom/src/debug.rs b/crates/patches/blitz-dom/src/debug.rs new file mode 100644 index 0000000..0d730a6 --- /dev/null +++ b/crates/patches/blitz-dom/src/debug.rs @@ -0,0 +1,139 @@ +use parley::layout::PositionedLayoutItem; + +use crate::BaseDocument; + +impl BaseDocument { + pub fn print_taffy_tree(&self) { + taffy::print_tree(self, taffy::NodeId::from(0usize)); + } + + pub fn debug_log_node(&self, node_id: usize) { + let node = &self.nodes[node_id]; + + #[cfg(feature = "tracing")] + { + tracing::info!("Layout: {:?}", &node.final_layout); + tracing::info!("Style: {:?}", &node.style); + } + + println!("\nNode {} {}", node.id, node.node_debug_str()); + + println!("Attrs:"); + + for attr in node.attrs().into_iter().flatten() { + println!(" {}: {}", attr.name.local, attr.value); + } + + if node.flags.is_inline_root() { + let inline_layout = &node + .data + .downcast_element() + .unwrap() + .inline_layout_data + .as_ref() + .unwrap(); + + println!( + "Size: {}x{}", + inline_layout.layout.width(), + inline_layout.layout.height() + ); + println!("Text content: {:?}", inline_layout.text); + println!("Inline Boxes:"); + for ibox in inline_layout.layout.inline_boxes() { + print!("(id: {}) ", ibox.id); + } + println!(); + println!("Lines:"); + for (i, line) in inline_layout.layout.lines().enumerate() { + println!("Line {i}:"); + for item in line.items() { + print!(" "); + match item { + PositionedLayoutItem::GlyphRun(run) => { + print!( + "RUN (x: {}, w: {}) ", + run.offset().round(), + run.run().advance() + ) + } + PositionedLayoutItem::InlineBox(ibox) => print!( + "BOX (id: {} x: {} y: {} w: {}, h: {})", + ibox.id, + ibox.x.round(), + ibox.y.round(), + ibox.width.round(), + ibox.height.round() + ), + } + println!(); + } + } + } + + let layout = &node.final_layout; + println!("Layout:"); + println!( + " x: {x} y: {y} w: {width} h: {height} content_w: {content_width} content_h: {content_height}", + x = layout.location.x, + y = layout.location.y, + width = layout.size.width, + height = layout.size.height, + content_width = layout.content_size.width, + content_height = layout.content_size.height, + ); + println!( + " border: l:{l} r:{r} t:{t} b:{b}", + l = layout.border.left, + r = layout.border.right, + t = layout.border.top, + b = layout.border.bottom, + ); + println!( + " padding: l:{l} r:{r} t:{t} b:{b}", + l = layout.padding.left, + r = layout.padding.right, + t = layout.padding.top, + b = layout.padding.bottom, + ); + println!( + " margin: l:{l} r:{r} t:{t} b:{b}", + l = layout.margin.left, + r = layout.margin.right, + t = layout.margin.top, + b = layout.margin.bottom, + ); + println!("Parent: {:?}", node.parent); + + let children: Vec<_> = node + .children + .iter() + .map(|id| &self.nodes[*id]) + .map(|node| (node.id, node.order(), node.node_debug_str())) + .collect(); + println!("Children: {children:?}"); + + println!("Layout Parent: {:?}", node.layout_parent.get()); + + let layout_children: Option> = node.layout_children.borrow().as_ref().map(|lc| { + lc.iter() + .map(|id| &self.nodes[*id]) + .map(|node| (node.id, node.order(), node.node_debug_str())) + .collect() + }); + if let Some(layout_children) = layout_children { + println!("Layout Children: {layout_children:?}"); + } + + let paint_children: Option> = node.paint_children.borrow().as_ref().map(|lc| { + lc.iter() + .map(|id| &self.nodes[*id]) + .map(|node| (node.id, node.order(), node.node_debug_str())) + .collect() + }); + if let Some(paint_children) = paint_children { + println!("Paint Children: {paint_children:?}"); + } + // taffy::print_tree(&self.dom, node_id.into()); + } +} diff --git a/crates/patches/blitz-dom/src/document.rs b/crates/patches/blitz-dom/src/document.rs new file mode 100644 index 0000000..5e06061 --- /dev/null +++ b/crates/patches/blitz-dom/src/document.rs @@ -0,0 +1,1394 @@ +use crate::events::handle_dom_event; +use crate::font_metrics::BlitzFontMetricsProvider; +use crate::layout::construct::{ + ConstructionTask, ConstructionTaskData, ConstructionTaskResult, ConstructionTaskResultData, + build_inline_layout_into, collect_layout_children, +}; +use crate::layout::damage::{ALL_DAMAGE, CONSTRUCT_BOX, CONSTRUCT_DESCENDENT, CONSTRUCT_FC}; +use crate::mutator::ViewportMut; +use crate::net::{CssHandler, Resource, StylesheetLoader}; +use crate::node::{ImageData, NodeFlags, RasterImageData, SpecialElementData, Status, TextBrush}; +use crate::stylo_to_cursor_icon::stylo_to_cursor_icon; +use crate::traversal::TreeTraverser; +use crate::url::DocumentUrl; +use crate::util::ImageType; +use crate::{ + DEFAULT_CSS, DocumentConfig, DocumentMutator, DummyHtmlParserProvider, ElementData, + EventDriver, HtmlParserProvider, NON_INCREMENTAL, Node, NodeData, NoopEventHandler, + TextNodeData, +}; +use blitz_traits::devtools::DevtoolSettings; +use blitz_traits::events::{DomEvent, HitResult, UiEvent}; +use blitz_traits::navigation::{DummyNavigationProvider, NavigationProvider}; +use blitz_traits::net::{DummyNetProvider, NetProvider, Request, SharedProvider}; +use blitz_traits::shell::{ColorScheme, DummyShellProvider, ShellProvider, Viewport}; +use cursor_icon::CursorIcon; +use debug_timer::debug_timer; +use linebender_resource_handle::Blob; +use markup5ever::local_name; +use parley::{FontContext, LayoutContext}; +use selectors::{Element, matching::QuirksMode}; +use slab::Slab; +use std::any::Any; +use std::cell::RefCell; +use std::collections::{BTreeMap, Bound, HashMap, HashSet}; +use std::ops::{Deref, DerefMut}; +use std::str::FromStr; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; +use std::task::Context as TaskContext; +use style::Atom; +use style::animation::DocumentAnimationSet; +use style::attr::{AttrIdentifier, AttrValue}; +use style::data::{ElementData as StyloElementData, ElementStyles}; +use style::media_queries::MediaType; +use style::properties::ComputedValues; +use style::properties::style_structs::Font; +use style::queries::values::PrefersColorScheme; +use style::selector_parser::ServoElementSnapshot; +use style::servo_arc::Arc as ServoArc; +use style::values::GenericAtomIdent; +use style::values::computed::Overflow; +use style::{ + dom::{TDocument, TNode}, + media_queries::{Device, MediaList}, + selector_parser::SnapshotMap, + shared_lock::{SharedRwLock, StylesheetGuards}, + stylesheets::{AllowImportRules, DocumentStyleSheet, Origin, Stylesheet}, + stylist::Stylist, +}; +use taffy::AvailableSpace; +use url::Url; + +#[cfg(feature = "parallel-construct")] +use rayon::prelude::*; + +thread_local! { + static LAYOUT_CTX: RefCell>>> = const { RefCell::new(None) }; + static FONT_CTX: RefCell>> = const { RefCell::new(None) }; +} + +#[cfg(feature = "incremental")] +use style::selector_parser::RestyleDamage; + +/// Abstraction over wrappers around [`BaseDocument`] to allow for them all to +/// be driven by [`blitz-shell`](https://docs.rs/blitz-shell) +pub trait Document: Deref + DerefMut + 'static { + /// Update the [`Document`] in response to a [`UiEvent`] (click, keypress, etc) + fn handle_ui_event(&mut self, event: UiEvent) { + let mut driver = EventDriver::new((*self).mutate(), NoopEventHandler); + driver.handle_ui_event(event); + } + + /// Poll any pending async operations, and flush changes to the underlying [`BaseDocument`] + fn poll(&mut self, task_context: Option) -> bool { + // Default implementation does nothing + let _ = task_context; + false + } + + fn as_any_mut(&mut self) -> &mut dyn Any; + + /// Get the [`Document`]'s id + fn id(&self) -> usize { + self.id + } +} + +pub struct BaseDocument { + /// ID of the document + id: usize, + + // Config + /// Base url for resolving linked resources (stylesheets, images, fonts, etc) + pub(crate) url: DocumentUrl, + // Devtool settings. Currently used to render debug overlays + pub(crate) devtool_settings: DevtoolSettings, + // Viewport details such as the dimensions, HiDPI scale, and zoom factor, + pub(crate) viewport: Viewport, + // Scroll within our viewport + pub(crate) viewport_scroll: crate::Point, + + /// A slab-backed tree of nodes + /// + /// We pin the tree to a guarantee to the nodes it creates that the tree is stable in memory. + /// There is no way to create the tree - publicly or privately - that would invalidate that invariant. + pub(crate) nodes: Box>, + + // Stylo + /// The Stylo engine + pub(crate) stylist: Stylist, + pub(crate) animations: DocumentAnimationSet, + /// Stylo shared lock + pub(crate) guard: SharedRwLock, + /// Stylo invalidation map. We insert into this map prior to mutating nodes. + pub(crate) snapshots: SnapshotMap, + + // Parley contexts + /// A Parley font context + pub(crate) font_ctx: Arc>, + /// A Parley layout context + pub(crate) layout_ctx: parley::LayoutContext, + + /// The node which is currently hovered (if any) + pub(crate) hover_node_id: Option, + /// The node which is currently focussed (if any) + pub focus_node_id: Option, + /// The node which is currently active (if any) + pub(crate) active_node_id: Option, + /// The node which recieved a mousedown event (if any) + pub(crate) mousedown_node_id: Option, + + /// Whether there are active CSS animations/transitions (so we should re-render every frame) + pub(crate) has_active_animations: bool, + /// Whether there is a element in the DOM (so we should re-render every frame) + pub(crate) has_canvas: bool, + + /// Map of node ID's for fast lookups + pub(crate) nodes_to_id: HashMap, + /// Map of `