blitz-pdf 0.1.2 → 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.
Files changed (64) hide show
  1. package/README.md +26 -0
  2. package/THIRD_PARTY_NOTICES.md +5 -2
  3. package/docs/layout-regressions.md +65 -0
  4. package/docs/pagination-regressions.md +89 -0
  5. package/package.json +2 -1
  6. package/vendor/README.md +35 -0
  7. package/vendor/blitz-dom/Cargo.toml +113 -0
  8. package/vendor/blitz-dom/LICENSE-APACHE +176 -0
  9. package/vendor/blitz-dom/LICENSE-MIT +23 -0
  10. package/vendor/blitz-dom/assets/default.css +1142 -0
  11. package/vendor/blitz-dom/assets/moz-bullet-font.otf +0 -0
  12. package/vendor/blitz-dom/src/accessibility.rs +255 -0
  13. package/vendor/blitz-dom/src/config.rs +97 -0
  14. package/vendor/blitz-dom/src/cssom.rs +971 -0
  15. package/vendor/blitz-dom/src/debug.rs +206 -0
  16. package/vendor/blitz-dom/src/document.rs +3395 -0
  17. package/vendor/blitz-dom/src/events/driver.rs +427 -0
  18. package/vendor/blitz-dom/src/events/focus.rs +40 -0
  19. package/vendor/blitz-dom/src/events/ime.rs +31 -0
  20. package/vendor/blitz-dom/src/events/keyboard.rs +174 -0
  21. package/vendor/blitz-dom/src/events/mod.rs +315 -0
  22. package/vendor/blitz-dom/src/events/pointer.rs +849 -0
  23. package/vendor/blitz-dom/src/font_metrics.rs +177 -0
  24. package/vendor/blitz-dom/src/form.rs +463 -0
  25. package/vendor/blitz-dom/src/html.rs +38 -0
  26. package/vendor/blitz-dom/src/iframe.rs +186 -0
  27. package/vendor/blitz-dom/src/layout/construct.rs +1328 -0
  28. package/vendor/blitz-dom/src/layout/damage.rs +642 -0
  29. package/vendor/blitz-dom/src/layout/inline.rs +1160 -0
  30. package/vendor/blitz-dom/src/layout/list.rs +237 -0
  31. package/vendor/blitz-dom/src/layout/mod.rs +969 -0
  32. package/vendor/blitz-dom/src/layout/paint_tree.rs +462 -0
  33. package/vendor/blitz-dom/src/layout/replaced.rs +439 -0
  34. package/vendor/blitz-dom/src/layout/table.rs +967 -0
  35. package/vendor/blitz-dom/src/layout/text_transform.rs +979 -0
  36. package/vendor/blitz-dom/src/layout/writing_mode.rs +437 -0
  37. package/vendor/blitz-dom/src/lib.rs +160 -0
  38. package/vendor/blitz-dom/src/mutator.rs +1818 -0
  39. package/vendor/blitz-dom/src/net.rs +649 -0
  40. package/vendor/blitz-dom/src/node/attributes.rs +60 -0
  41. package/vendor/blitz-dom/src/node/custom_widget.rs +178 -0
  42. package/vendor/blitz-dom/src/node/element.rs +1106 -0
  43. package/vendor/blitz-dom/src/node/mod.rs +30 -0
  44. package/vendor/blitz-dom/src/node/node.rs +2036 -0
  45. package/vendor/blitz-dom/src/node/scrollbar.rs +237 -0
  46. package/vendor/blitz-dom/src/node/serialize.rs +225 -0
  47. package/vendor/blitz-dom/src/node/stylo_data.rs +142 -0
  48. package/vendor/blitz-dom/src/node/svg.rs +265 -0
  49. package/vendor/blitz-dom/src/node/text.rs +804 -0
  50. package/vendor/blitz-dom/src/query_selector.rs +275 -0
  51. package/vendor/blitz-dom/src/resolve.rs +474 -0
  52. package/vendor/blitz-dom/src/resolved_style.rs +797 -0
  53. package/vendor/blitz-dom/src/scrolling.rs +780 -0
  54. package/vendor/blitz-dom/src/selection.rs +122 -0
  55. package/vendor/blitz-dom/src/stylo.rs +1518 -0
  56. package/vendor/blitz-dom/src/stylo_device.rs +88 -0
  57. package/vendor/blitz-dom/src/stylo_to_cursor_icon.rs +49 -0
  58. package/vendor/blitz-dom/src/stylo_to_kurbo.rs +129 -0
  59. package/vendor/blitz-dom/src/stylo_to_parley.rs +655 -0
  60. package/vendor/blitz-dom/src/traversal.rs +600 -0
  61. package/vendor/blitz-dom/src/tree.rs +136 -0
  62. package/vendor/blitz-dom/src/url.rs +63 -0
  63. package/vendor/blitz-dom/src/util.rs +256 -0
  64. package/wasm/blitz_pdf_bg.wasm +0 -0
@@ -0,0 +1,275 @@
1
+ use blitz_traits::node_id::NodeId;
2
+ use selectors::SelectorList;
3
+ use smallvec::SmallVec;
4
+ use style::dom::{TDocument, TNode};
5
+ use style::dom_apis::{
6
+ MayUseInvalidation, QueryAll, QueryFirst, element_closest, element_matches, query_selector,
7
+ };
8
+ use style::selector_parser::{SelectorImpl, SelectorParser};
9
+ use style_traits::ParseError;
10
+
11
+ use crate::{BaseDocument, Node};
12
+
13
+ impl BaseDocument {
14
+ /// Find the node with the specified id attribute (if one exists).
15
+ /// If multiple nodes have the same id, the first in tree order is returned.
16
+ pub fn get_element_by_id(&self, id: &str) -> Option<NodeId> {
17
+ match self.nodes_to_id.get(id)?.as_slice() {
18
+ [] => None,
19
+ [node_id] => Some(*node_id),
20
+ candidates => self.first_in_tree_order(candidates),
21
+ }
22
+ }
23
+
24
+ /// Find the first of `candidates` in tree order
25
+ fn first_in_tree_order(&self, candidates: &[NodeId]) -> Option<NodeId> {
26
+ let mut stack = vec![self.root_node_id];
27
+ while let Some(node_id) = stack.pop() {
28
+ if candidates.contains(&node_id) {
29
+ return Some(node_id);
30
+ }
31
+ stack.extend(self.nodes[node_id].children.iter().rev().copied());
32
+ }
33
+ None
34
+ }
35
+
36
+ /// Add a node to the id-to-node map
37
+ pub(crate) fn add_to_id_map(&mut self, id: &str, node_id: NodeId) {
38
+ if id.is_empty() {
39
+ return;
40
+ }
41
+ let node_ids = self.nodes_to_id.entry(id.to_string()).or_default();
42
+ if !node_ids.contains(&node_id) {
43
+ node_ids.push(node_id);
44
+ }
45
+ }
46
+
47
+ /// Remove a node from the id-to-node map
48
+ pub(crate) fn remove_from_id_map(&mut self, id: &str, node_id: NodeId) {
49
+ if let Some(node_ids) = self.nodes_to_id.get_mut(id) {
50
+ node_ids.retain(|nid| *nid != node_id);
51
+ if node_ids.is_empty() {
52
+ self.nodes_to_id.remove(id);
53
+ }
54
+ }
55
+ }
56
+
57
+ /// Find the first node that matches the selector specified as a string
58
+ /// Returns:
59
+ /// - Err(_) if parsing the selector fails
60
+ /// - Ok(None) if nothing matches
61
+ /// - Ok(Some(node_id)) with the first node ID that matches if one is found
62
+ pub fn query_selector(&self, selector: &str) -> Result<Option<NodeId>, ParseError> {
63
+ self.query_selector_in(self.root_node_id, selector)
64
+ }
65
+
66
+ /// Find the first descendant of `scope` that matches the selector specified
67
+ /// as a string.
68
+ ///
69
+ /// The scope node itself is never matched. Selector parts may match nodes
70
+ /// outside the scope while evaluating relationships between descendants.
71
+ ///
72
+ /// Returns:
73
+ /// - `Err(_)` if parsing the selector fails
74
+ /// - `Ok(None)` if nothing matches
75
+ /// - `Ok(Some(node_id))` with the first matching descendant ID otherwise
76
+ pub fn query_selector_in(
77
+ &self,
78
+ scope: NodeId,
79
+ selector: &str,
80
+ ) -> Result<Option<NodeId>, ParseError> {
81
+ let selector_list = self.try_parse_selector_list(selector)?;
82
+ Ok(self.query_selector_in_raw(scope, &selector_list))
83
+ }
84
+
85
+ /// Find the first descendant of the document root that matches the
86
+ /// selector(s) specified in `selector_list`.
87
+ ///
88
+ /// The document root itself is never matched. Selector parts may match
89
+ /// nodes outside the scope while evaluating relationships between
90
+ /// descendants.
91
+ pub fn query_selector_raw(&self, selector_list: &SelectorList<SelectorImpl>) -> Option<NodeId> {
92
+ self.query_selector_in_raw(self.root_node_id, selector_list)
93
+ }
94
+
95
+ /// Find the first descendant of `scope` that matches the selector(s)
96
+ /// specified in `selector_list`.
97
+ ///
98
+ /// The scope node itself is never matched. Selector parts may match nodes
99
+ /// outside the scope while evaluating relationships between descendants.
100
+ pub fn query_selector_in_raw(
101
+ &self,
102
+ scope: NodeId,
103
+ selector_list: &SelectorList<SelectorImpl>,
104
+ ) -> Option<NodeId> {
105
+ let root_node = &self.nodes[scope];
106
+ let mut result = None;
107
+ query_selector::<&Node, QueryFirst>(
108
+ root_node,
109
+ selector_list,
110
+ &mut result,
111
+ self.may_use_invalidation_for(scope),
112
+ );
113
+
114
+ result.map(|node| node.id)
115
+ }
116
+
117
+ /// Find all nodes that match the selector specified as a string
118
+ /// Returns:
119
+ /// - `Err(_)` if parsing the selector fails
120
+ /// - `Ok(SmallVec<usize>)` with all matching nodes otherwise
121
+ pub fn query_selector_all(&self, selector: &str) -> Result<SmallVec<[NodeId; 32]>, ParseError> {
122
+ self.query_selector_all_in(self.root_node_id, selector)
123
+ }
124
+
125
+ /// Find all descendants of `scope` that match the selector specified as a
126
+ /// string, in tree order.
127
+ ///
128
+ /// The scope node itself is never matched. Selector parts may match nodes
129
+ /// outside the scope while evaluating relationships between descendants.
130
+ ///
131
+ /// Returns:
132
+ /// - `Err(_)` if parsing the selector fails
133
+ /// - `Ok(_)` with all matching descendant IDs otherwise
134
+ pub fn query_selector_all_in(
135
+ &self,
136
+ scope: NodeId,
137
+ selector: &str,
138
+ ) -> Result<SmallVec<[NodeId; 32]>, ParseError> {
139
+ let selector_list = self.try_parse_selector_list(selector)?;
140
+ Ok(self.query_selector_all_in_raw(scope, &selector_list))
141
+ }
142
+
143
+ /// Find all descendants of the document root that match the selector(s)
144
+ /// specified in `selector_list`, in tree order.
145
+ ///
146
+ /// The document root itself is never matched. Selector parts may match
147
+ /// nodes outside the scope while evaluating relationships between
148
+ /// descendants.
149
+ pub fn query_selector_all_raw(
150
+ &self,
151
+ selector_list: &SelectorList<SelectorImpl>,
152
+ ) -> SmallVec<[NodeId; 32]> {
153
+ self.query_selector_all_in_raw(self.root_node_id, selector_list)
154
+ }
155
+
156
+ /// Find all descendants of `scope` that match the selector(s) specified in
157
+ /// `selector_list`, in tree order.
158
+ ///
159
+ /// The scope node itself is never matched. Selector parts may match nodes
160
+ /// outside the scope while evaluating relationships between descendants.
161
+ pub fn query_selector_all_in_raw(
162
+ &self,
163
+ scope: NodeId,
164
+ selector_list: &SelectorList<SelectorImpl>,
165
+ ) -> SmallVec<[NodeId; 32]> {
166
+ let root_node = &self.nodes[scope];
167
+ let mut results = SmallVec::new();
168
+ query_selector::<&Node, QueryAll>(
169
+ root_node,
170
+ selector_list,
171
+ &mut results,
172
+ self.may_use_invalidation_for(scope),
173
+ );
174
+
175
+ results.iter().map(|node| node.id).collect()
176
+ }
177
+
178
+ fn may_use_invalidation_for(&self, scope: NodeId) -> MayUseInvalidation {
179
+ if scope == self.root_node_id {
180
+ MayUseInvalidation::Yes
181
+ } else {
182
+ MayUseInvalidation::No
183
+ }
184
+ }
185
+
186
+ /// Test whether the node identified by `node_id` matches the selector
187
+ /// specified as a string.
188
+ ///
189
+ /// Non-element nodes never match.
190
+ pub fn matches_selector(&self, node_id: NodeId, selector: &str) -> Result<bool, ParseError> {
191
+ let selector_list = self.try_parse_selector_list(selector)?;
192
+ Ok(self.nodes[node_id].matches_selector_raw(&selector_list))
193
+ }
194
+
195
+ /// Find the closest matching element at or above the node identified by
196
+ /// `node_id`.
197
+ ///
198
+ /// Non-element nodes never match and return `None`.
199
+ pub fn closest(&self, node_id: NodeId, selector: &str) -> Result<Option<NodeId>, ParseError> {
200
+ let selector_list = self.try_parse_selector_list(selector)?;
201
+ Ok(self.nodes[node_id].closest_raw(&selector_list))
202
+ }
203
+
204
+ pub fn try_parse_selector_list(
205
+ &self,
206
+ input: &str,
207
+ ) -> Result<SelectorList<SelectorImpl>, ParseError> {
208
+ let url_extra_data = self.url.url_extra_data();
209
+ SelectorParser::parse_author_origin_no_namespace(input, &url_extra_data)
210
+ }
211
+ }
212
+
213
+ impl Node {
214
+ /// Find the first descendant of this node that matches the selector(s)
215
+ /// specified in `selector_list`.
216
+ ///
217
+ /// The scope node itself is never matched. Selector parts may match nodes
218
+ /// outside the scope while evaluating relationships between descendants.
219
+ ///
220
+ /// Text and comment scope nodes return no matches.
221
+ pub fn query_selector_raw(&self, selector_list: &SelectorList<SelectorImpl>) -> Option<NodeId> {
222
+ let mut result = None;
223
+ query_selector::<&Node, QueryFirst>(
224
+ self,
225
+ selector_list,
226
+ &mut result,
227
+ MayUseInvalidation::No,
228
+ );
229
+ result.map(|node| node.id)
230
+ }
231
+
232
+ /// Find all descendants of this node that match the selector(s) specified
233
+ /// in `selector_list`, in tree order.
234
+ ///
235
+ /// The scope node itself is never matched. Selector parts may match nodes
236
+ /// outside the scope while evaluating relationships between descendants.
237
+ ///
238
+ /// Text and comment scope nodes return no matches.
239
+ pub fn query_selector_all_raw(
240
+ &self,
241
+ selector_list: &SelectorList<SelectorImpl>,
242
+ ) -> SmallVec<[NodeId; 32]> {
243
+ let mut results = SmallVec::new();
244
+ query_selector::<&Node, QueryAll>(
245
+ self,
246
+ selector_list,
247
+ &mut results,
248
+ MayUseInvalidation::No,
249
+ );
250
+ results.iter().map(|node| node.id).collect()
251
+ }
252
+
253
+ /// Test whether this element matches the selector(s) specified in
254
+ /// `selector_list`.
255
+ ///
256
+ /// Non-element nodes never match.
257
+ pub fn matches_selector_raw(&self, selector_list: &SelectorList<SelectorImpl>) -> bool {
258
+ if !self.is_element() {
259
+ return false;
260
+ }
261
+
262
+ element_matches(&self, selector_list, self.owner_doc().quirks_mode())
263
+ }
264
+
265
+ /// Find the closest matching element at or above this element.
266
+ ///
267
+ /// Non-element nodes never match and return `None`.
268
+ pub fn closest_raw(&self, selector_list: &SelectorList<SelectorImpl>) -> Option<NodeId> {
269
+ if !self.is_element() {
270
+ return None;
271
+ }
272
+
273
+ element_closest(self, selector_list, self.owner_doc().quirks_mode()).map(|node| node.id)
274
+ }
275
+ }