innertext 0.2.3__tar.gz → 0.2.4__tar.gz
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.
- {innertext-0.2.3 → innertext-0.2.4}/Cargo.lock +4 -4
- {innertext-0.2.3 → innertext-0.2.4}/Cargo.toml +1 -1
- {innertext-0.2.3 → innertext-0.2.4}/PKG-INFO +1 -1
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/src/inner_text.rs +44 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/tests/spec_behavior.rs +42 -0
- {innertext-0.2.3 → innertext-0.2.4}/pyproject.toml +1 -1
- {innertext-0.2.3 → innertext-0.2.4}/README.md +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/bindings/innertext-python/Cargo.toml +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/bindings/innertext-python/README.md +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/bindings/innertext-python/src/lib.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/Cargo.toml +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/src/css.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/src/lib.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/src/model.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/src/render.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/src/text_content.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/crates/innertext-core/tests/chromium_parity.rs +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/python/innertext/__init__.py +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/python/innertext/__init__.pyi +0 -0
- {innertext-0.2.3 → innertext-0.2.4}/python/innertext/py.typed +0 -0
|
@@ -115,7 +115,7 @@ dependencies = [
|
|
|
115
115
|
|
|
116
116
|
[[package]]
|
|
117
117
|
name = "innertext-core"
|
|
118
|
-
version = "0.2.
|
|
118
|
+
version = "0.2.4"
|
|
119
119
|
dependencies = [
|
|
120
120
|
"html5ever",
|
|
121
121
|
"markup5ever",
|
|
@@ -128,7 +128,7 @@ dependencies = [
|
|
|
128
128
|
|
|
129
129
|
[[package]]
|
|
130
130
|
name = "innertext-java"
|
|
131
|
-
version = "0.2.
|
|
131
|
+
version = "0.2.4"
|
|
132
132
|
dependencies = [
|
|
133
133
|
"innertext-core",
|
|
134
134
|
"jni",
|
|
@@ -137,7 +137,7 @@ dependencies = [
|
|
|
137
137
|
|
|
138
138
|
[[package]]
|
|
139
139
|
name = "innertext-node"
|
|
140
|
-
version = "0.2.
|
|
140
|
+
version = "0.2.4"
|
|
141
141
|
dependencies = [
|
|
142
142
|
"innertext-core",
|
|
143
143
|
"napi",
|
|
@@ -146,7 +146,7 @@ dependencies = [
|
|
|
146
146
|
|
|
147
147
|
[[package]]
|
|
148
148
|
name = "innertext-python"
|
|
149
|
-
version = "0.2.
|
|
149
|
+
version = "0.2.4"
|
|
150
150
|
dependencies = [
|
|
151
151
|
"innertext-core",
|
|
152
152
|
"pyo3",
|
|
@@ -22,6 +22,8 @@ pub(crate) fn extract(dom: &RcDom) -> String {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
let normalized = normalize_tokens(tokens);
|
|
25
|
+
let normalized = drop_inter_block_separator_spaces(normalized);
|
|
26
|
+
let normalized = drop_boundaries_between_required_breaks(normalized);
|
|
25
27
|
let folded = fold_required_break_runs(normalized);
|
|
26
28
|
serialize_tokens(folded)
|
|
27
29
|
}
|
|
@@ -133,6 +135,48 @@ fn normalize_tokens(mut tokens: Vec<RenderToken>) -> Vec<RenderToken> {
|
|
|
133
135
|
tokens
|
|
134
136
|
}
|
|
135
137
|
|
|
138
|
+
fn drop_inter_block_separator_spaces(tokens: Vec<RenderToken>) -> Vec<RenderToken> {
|
|
139
|
+
let mut out = Vec::with_capacity(tokens.len());
|
|
140
|
+
|
|
141
|
+
for i in 0..tokens.len() {
|
|
142
|
+
if let RenderToken::Text(text) = &tokens[i] {
|
|
143
|
+
let prev_is_marker = i > 0
|
|
144
|
+
&& matches!(
|
|
145
|
+
tokens.get(i - 1),
|
|
146
|
+
Some(RenderToken::RequiredBreak(_) | RenderToken::CollapseBoundary)
|
|
147
|
+
);
|
|
148
|
+
let next_is_marker = matches!(
|
|
149
|
+
tokens.get(i + 1),
|
|
150
|
+
Some(RenderToken::RequiredBreak(_) | RenderToken::CollapseBoundary)
|
|
151
|
+
);
|
|
152
|
+
if text.chars().all(|ch| ch == ' ') && prev_is_marker && next_is_marker {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
out.push(tokens[i].clone());
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
out
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
fn drop_boundaries_between_required_breaks(tokens: Vec<RenderToken>) -> Vec<RenderToken> {
|
|
163
|
+
let mut out = Vec::with_capacity(tokens.len());
|
|
164
|
+
|
|
165
|
+
for i in 0..tokens.len() {
|
|
166
|
+
if matches!(tokens[i], RenderToken::CollapseBoundary) {
|
|
167
|
+
let prev_is_break =
|
|
168
|
+
i > 0 && matches!(tokens.get(i - 1), Some(RenderToken::RequiredBreak(_)));
|
|
169
|
+
let next_is_break = matches!(tokens.get(i + 1), Some(RenderToken::RequiredBreak(_)));
|
|
170
|
+
if prev_is_break && next_is_break {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
out.push(tokens[i].clone());
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
out
|
|
178
|
+
}
|
|
179
|
+
|
|
136
180
|
fn fold_required_break_runs(tokens: Vec<RenderToken>) -> Vec<RenderToken> {
|
|
137
181
|
let mut out = Vec::new();
|
|
138
182
|
let mut i = 0;
|
|
@@ -51,6 +51,48 @@ fn sibling_blocks_have_two_newlines_between_them() {
|
|
|
51
51
|
assert_eq!(got, "Block A\nBlock B");
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
#[test]
|
|
55
|
+
fn formatting_whitespace_between_p_tags_does_not_change_inner_text() {
|
|
56
|
+
let compact = "<p>Some text</p><p>Some more text which <span>is inside a span</span></p><p style='display: none'>This text is hidden</p>";
|
|
57
|
+
let spaced = "<p>Some text</p>\n\n<p>Some more text which <span>is inside a span</span></p><p style='display: none'>This text is hidden</p>";
|
|
58
|
+
let heavily_spaced = "<p>Some text</p>\n\n\n\n <p>Some more text which <span>is inside a span</span></p><p style='display: none'>This text is hidden</p>";
|
|
59
|
+
|
|
60
|
+
let expected = inner_text_from_html(compact).expect("must extract compact text");
|
|
61
|
+
let spaced_actual = inner_text_from_html(spaced).expect("must extract spaced text");
|
|
62
|
+
let heavily_spaced_actual =
|
|
63
|
+
inner_text_from_html(heavily_spaced).expect("must extract heavily spaced text");
|
|
64
|
+
|
|
65
|
+
assert_eq!(spaced_actual, expected);
|
|
66
|
+
assert_eq!(heavily_spaced_actual, expected);
|
|
67
|
+
assert_eq!(
|
|
68
|
+
expected,
|
|
69
|
+
"Some text\n\nSome more text which is inside a span"
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#[test]
|
|
74
|
+
fn formatting_whitespace_between_div_tags_does_not_change_inner_text() {
|
|
75
|
+
let compact = "<div>Block A</div><div>Block B</div>";
|
|
76
|
+
let spaced = "<div>Block A</div>\n\n\n <div>Block B</div>";
|
|
77
|
+
|
|
78
|
+
let expected = inner_text_from_html(compact).expect("must extract compact text");
|
|
79
|
+
let actual = inner_text_from_html(spaced).expect("must extract spaced text");
|
|
80
|
+
|
|
81
|
+
assert_eq!(actual, expected);
|
|
82
|
+
assert_eq!(expected, "Block A\nBlock B");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#[test]
|
|
86
|
+
fn hidden_block_with_separator_whitespace_does_not_add_extra_gaps() {
|
|
87
|
+
let compact = "<p>One</p><p style='display:none'>Hidden</p><p>Two</p>";
|
|
88
|
+
let spaced = "<p>One</p>\n\n\n<p style='display:none'>Hidden</p>\n\n\n<p>Two</p>";
|
|
89
|
+
|
|
90
|
+
let expected = inner_text_from_html(compact).expect("must extract compact text");
|
|
91
|
+
let actual = inner_text_from_html(spaced).expect("must extract spaced text");
|
|
92
|
+
|
|
93
|
+
assert_eq!(actual, expected);
|
|
94
|
+
}
|
|
95
|
+
|
|
54
96
|
// ── outerText getter ───────────────────────────────────────────────────────
|
|
55
97
|
|
|
56
98
|
#[test]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|