blitz-pdf 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/THIRD_PARTY_NOTICES.md +5 -2
- package/docs/layout-regressions.md +65 -0
- package/docs/pagination-regressions.md +7 -6
- package/package.json +1 -1
- package/vendor/README.md +35 -0
- package/vendor/blitz-dom/Cargo.toml +113 -0
- package/vendor/blitz-dom/LICENSE-APACHE +176 -0
- package/vendor/blitz-dom/LICENSE-MIT +23 -0
- package/vendor/blitz-dom/assets/default.css +1142 -0
- package/vendor/blitz-dom/assets/moz-bullet-font.otf +0 -0
- package/vendor/blitz-dom/src/accessibility.rs +255 -0
- package/vendor/blitz-dom/src/config.rs +97 -0
- package/vendor/blitz-dom/src/cssom.rs +971 -0
- package/vendor/blitz-dom/src/debug.rs +206 -0
- package/vendor/blitz-dom/src/document.rs +3395 -0
- package/vendor/blitz-dom/src/events/driver.rs +427 -0
- package/vendor/blitz-dom/src/events/focus.rs +40 -0
- package/vendor/blitz-dom/src/events/ime.rs +31 -0
- package/vendor/blitz-dom/src/events/keyboard.rs +174 -0
- package/vendor/blitz-dom/src/events/mod.rs +315 -0
- package/vendor/blitz-dom/src/events/pointer.rs +849 -0
- package/vendor/blitz-dom/src/font_metrics.rs +177 -0
- package/vendor/blitz-dom/src/form.rs +463 -0
- package/vendor/blitz-dom/src/html.rs +38 -0
- package/vendor/blitz-dom/src/iframe.rs +186 -0
- package/vendor/blitz-dom/src/layout/construct.rs +1328 -0
- package/vendor/blitz-dom/src/layout/damage.rs +642 -0
- package/vendor/blitz-dom/src/layout/inline.rs +1160 -0
- package/vendor/blitz-dom/src/layout/list.rs +237 -0
- package/vendor/blitz-dom/src/layout/mod.rs +969 -0
- package/vendor/blitz-dom/src/layout/paint_tree.rs +462 -0
- package/vendor/blitz-dom/src/layout/replaced.rs +439 -0
- package/vendor/blitz-dom/src/layout/table.rs +967 -0
- package/vendor/blitz-dom/src/layout/text_transform.rs +979 -0
- package/vendor/blitz-dom/src/layout/writing_mode.rs +437 -0
- package/vendor/blitz-dom/src/lib.rs +160 -0
- package/vendor/blitz-dom/src/mutator.rs +1818 -0
- package/vendor/blitz-dom/src/net.rs +649 -0
- package/vendor/blitz-dom/src/node/attributes.rs +60 -0
- package/vendor/blitz-dom/src/node/custom_widget.rs +178 -0
- package/vendor/blitz-dom/src/node/element.rs +1106 -0
- package/vendor/blitz-dom/src/node/mod.rs +30 -0
- package/vendor/blitz-dom/src/node/node.rs +2036 -0
- package/vendor/blitz-dom/src/node/scrollbar.rs +237 -0
- package/vendor/blitz-dom/src/node/serialize.rs +225 -0
- package/vendor/blitz-dom/src/node/stylo_data.rs +142 -0
- package/vendor/blitz-dom/src/node/svg.rs +265 -0
- package/vendor/blitz-dom/src/node/text.rs +804 -0
- package/vendor/blitz-dom/src/query_selector.rs +275 -0
- package/vendor/blitz-dom/src/resolve.rs +474 -0
- package/vendor/blitz-dom/src/resolved_style.rs +797 -0
- package/vendor/blitz-dom/src/scrolling.rs +780 -0
- package/vendor/blitz-dom/src/selection.rs +122 -0
- package/vendor/blitz-dom/src/stylo.rs +1518 -0
- package/vendor/blitz-dom/src/stylo_device.rs +88 -0
- package/vendor/blitz-dom/src/stylo_to_cursor_icon.rs +49 -0
- package/vendor/blitz-dom/src/stylo_to_kurbo.rs +129 -0
- package/vendor/blitz-dom/src/stylo_to_parley.rs +655 -0
- package/vendor/blitz-dom/src/traversal.rs +600 -0
- package/vendor/blitz-dom/src/tree.rs +136 -0
- package/vendor/blitz-dom/src/url.rs +63 -0
- package/vendor/blitz-dom/src/util.rs +256 -0
- package/wasm/blitz_pdf_bg.wasm +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//! Text selection state and logic for non-input elements.
|
|
2
|
+
//!
|
|
3
|
+
//! This module handles text selection across inline roots in the document,
|
|
4
|
+
//! including support for anonymous blocks which have unstable IDs across
|
|
5
|
+
//! layout reconstruction.
|
|
6
|
+
|
|
7
|
+
use blitz_traits::node_id::NodeId;
|
|
8
|
+
|
|
9
|
+
/// Represents one endpoint (anchor or focus) of a text selection.
|
|
10
|
+
///
|
|
11
|
+
/// For regular nodes, `node_or_parent` contains the node ID directly.
|
|
12
|
+
/// For anonymous blocks, `node_or_parent` contains the parent ID and
|
|
13
|
+
/// `sibling_index` contains the index among anonymous siblings.
|
|
14
|
+
#[derive(Clone, Debug, Default)]
|
|
15
|
+
pub struct SelectionEndpoint {
|
|
16
|
+
/// For regular nodes: the node ID directly.
|
|
17
|
+
/// For anonymous blocks: the parent ID (requires lookup via sibling_index).
|
|
18
|
+
pub(crate) node_or_parent: Option<NodeId>,
|
|
19
|
+
/// Byte offset within the inline root's text
|
|
20
|
+
pub offset: usize,
|
|
21
|
+
/// For anonymous blocks only: index among anonymous siblings.
|
|
22
|
+
/// When Some, node_or_parent is a parent ID requiring lookup.
|
|
23
|
+
pub(crate) sibling_index: Option<usize>,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
impl SelectionEndpoint {
|
|
27
|
+
/// Create a new endpoint at the given node and offset (for non-anonymous nodes)
|
|
28
|
+
fn new(node: NodeId, offset: usize) -> Self {
|
|
29
|
+
Self {
|
|
30
|
+
node_or_parent: Some(node),
|
|
31
|
+
offset,
|
|
32
|
+
sibling_index: None,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Check if this endpoint is set
|
|
37
|
+
pub fn is_some(&self) -> bool {
|
|
38
|
+
self.node_or_parent.is_some()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// Clear this endpoint
|
|
42
|
+
pub fn clear(&mut self) {
|
|
43
|
+
self.node_or_parent = None;
|
|
44
|
+
self.offset = 0;
|
|
45
|
+
self.sibling_index = None;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Resolve the node ID, using a lookup function for anonymous blocks.
|
|
49
|
+
pub fn resolve_node_id(
|
|
50
|
+
&self,
|
|
51
|
+
lookup_fn: impl FnOnce(NodeId, usize) -> Option<NodeId>,
|
|
52
|
+
) -> Option<NodeId> {
|
|
53
|
+
match (self.node_or_parent, self.sibling_index) {
|
|
54
|
+
(Some(node), None) => Some(node),
|
|
55
|
+
(Some(parent), Some(idx)) => lookup_fn(parent, idx),
|
|
56
|
+
_ => None,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// Set as a direct node reference (for regular nodes)
|
|
61
|
+
pub fn set_node(&mut self, node: NodeId, offset: usize) {
|
|
62
|
+
self.node_or_parent = Some(node);
|
|
63
|
+
self.offset = offset;
|
|
64
|
+
self.sibling_index = None;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/// Set as an anonymous block reference
|
|
68
|
+
pub fn set_anonymous(&mut self, parent: NodeId, sibling_index: usize, offset: usize) {
|
|
69
|
+
self.node_or_parent = Some(parent);
|
|
70
|
+
self.offset = offset;
|
|
71
|
+
self.sibling_index = Some(sibling_index);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/// Text selection state for non-input elements.
|
|
76
|
+
///
|
|
77
|
+
/// Tracks both the anchor (where selection started) and focus (where it currently ends).
|
|
78
|
+
/// For anonymous blocks, we store stable parent references since anonymous block IDs
|
|
79
|
+
/// can change during layout reconstruction.
|
|
80
|
+
#[derive(Clone, Debug, Default)]
|
|
81
|
+
pub struct TextSelection {
|
|
82
|
+
/// The anchor point (where selection started via mousedown)
|
|
83
|
+
pub anchor: SelectionEndpoint,
|
|
84
|
+
/// The focus point (where selection currently ends, updated during drag)
|
|
85
|
+
pub focus: SelectionEndpoint,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
impl TextSelection {
|
|
89
|
+
/// Create a selection spanning from anchor to focus
|
|
90
|
+
pub fn new(
|
|
91
|
+
anchor_node: NodeId,
|
|
92
|
+
anchor_offset: usize,
|
|
93
|
+
focus_node: NodeId,
|
|
94
|
+
focus_offset: usize,
|
|
95
|
+
) -> Self {
|
|
96
|
+
Self {
|
|
97
|
+
anchor: SelectionEndpoint::new(anchor_node, anchor_offset),
|
|
98
|
+
focus: SelectionEndpoint::new(focus_node, focus_offset),
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// Check if there is an active (non-empty) selection.
|
|
103
|
+
/// Note: For anonymous blocks this compares parent+sibling_index, not resolved node IDs.
|
|
104
|
+
pub fn is_active(&self) -> bool {
|
|
105
|
+
self.anchor.is_some()
|
|
106
|
+
&& self.focus.is_some()
|
|
107
|
+
&& (self.anchor.node_or_parent != self.focus.node_or_parent
|
|
108
|
+
|| self.anchor.sibling_index != self.focus.sibling_index
|
|
109
|
+
|| self.anchor.offset != self.focus.offset)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// Clear the selection
|
|
113
|
+
pub fn clear(&mut self) {
|
|
114
|
+
self.anchor.clear();
|
|
115
|
+
self.focus.clear();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// Update the focus endpoint (for non-anonymous nodes)
|
|
119
|
+
pub fn set_focus(&mut self, node: NodeId, offset: usize) {
|
|
120
|
+
self.focus.set_node(node, offset);
|
|
121
|
+
}
|
|
122
|
+
}
|