html-to-markdown 3.4.0 → 3.6.0.pre.rc.23
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.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +347 -0
- data/Steepfile +10 -2
- data/ext/html_to_markdown_rb/Cargo.toml +3 -2
- data/ext/html_to_markdown_rb/extconf.rb +5 -5
- data/ext/html_to_markdown_rb/native/Cargo.lock +962 -0
- data/ext/html_to_markdown_rb/native/Cargo.toml +6 -11
- data/ext/html_to_markdown_rb/native/extconf.rb +14 -0
- data/ext/html_to_markdown_rb/src/lib.rs +1715 -646
- data/lib/html_to_markdown/native.rb +913 -37
- data/lib/html_to_markdown/version.rb +3 -3
- data/lib/html_to_markdown.rb +9 -4
- data/lib/html_to_markdown_rb.so +0 -0
- data/sig/types.rbs +59 -292
- metadata +32 -179
- data/ext/html_to_markdown_rb/Makefile +0 -592
- data/lib/bin/html-to-markdown +0 -0
- data/vendor/Cargo.toml +0 -33
- data/vendor/html-to-markdown-rs/Cargo.toml +0 -54
- data/vendor/html-to-markdown-rs/README.md +0 -278
- data/vendor/html-to-markdown-rs/examples/basic.rs +0 -24
- data/vendor/html-to-markdown-rs/examples/table.rs +0 -25
- data/vendor/html-to-markdown-rs/examples/test_deser.rs +0 -12
- data/vendor/html-to-markdown-rs/examples/test_escape.rs +0 -58
- data/vendor/html-to-markdown-rs/examples/test_inline_formatting.rs +0 -113
- data/vendor/html-to-markdown-rs/examples/test_lists.rs +0 -39
- data/vendor/html-to-markdown-rs/examples/test_semantic_tags.rs +0 -89
- data/vendor/html-to-markdown-rs/examples/test_tables.rs +0 -100
- data/vendor/html-to-markdown-rs/examples/test_task_lists.rs +0 -61
- data/vendor/html-to-markdown-rs/examples/test_whitespace.rs +0 -34
- data/vendor/html-to-markdown-rs/src/convert_api.rs +0 -349
- data/vendor/html-to-markdown-rs/src/converter/block/blockquote.rs +0 -178
- data/vendor/html-to-markdown-rs/src/converter/block/container.rs +0 -114
- data/vendor/html-to-markdown-rs/src/converter/block/div.rs +0 -149
- data/vendor/html-to-markdown-rs/src/converter/block/heading.rs +0 -428
- data/vendor/html-to-markdown-rs/src/converter/block/horizontal_rule.rs +0 -103
- data/vendor/html-to-markdown-rs/src/converter/block/line_break.rs +0 -89
- data/vendor/html-to-markdown-rs/src/converter/block/mod.rs +0 -10
- data/vendor/html-to-markdown-rs/src/converter/block/paragraph.rs +0 -140
- data/vendor/html-to-markdown-rs/src/converter/block/preformatted.rs +0 -298
- data/vendor/html-to-markdown-rs/src/converter/block/table/builder.rs +0 -453
- data/vendor/html-to-markdown-rs/src/converter/block/table/caption.rs +0 -44
- data/vendor/html-to-markdown-rs/src/converter/block/table/cell.rs +0 -276
- data/vendor/html-to-markdown-rs/src/converter/block/table/cells.rs +0 -336
- data/vendor/html-to-markdown-rs/src/converter/block/table/layout.rs +0 -58
- data/vendor/html-to-markdown-rs/src/converter/block/table/mod.rs +0 -266
- data/vendor/html-to-markdown-rs/src/converter/block/table/scanner.rs +0 -146
- data/vendor/html-to-markdown-rs/src/converter/block/table/utils.rs +0 -34
- data/vendor/html-to-markdown-rs/src/converter/block/unknown.rs +0 -138
- data/vendor/html-to-markdown-rs/src/converter/context.rs +0 -208
- data/vendor/html-to-markdown-rs/src/converter/dom_context.rs +0 -337
- data/vendor/html-to-markdown-rs/src/converter/form/elements.rs +0 -770
- data/vendor/html-to-markdown-rs/src/converter/form/mod.rs +0 -82
- data/vendor/html-to-markdown-rs/src/converter/format/djot.rs +0 -64
- data/vendor/html-to-markdown-rs/src/converter/format/markdown.rs +0 -59
- data/vendor/html-to-markdown-rs/src/converter/format/mod.rs +0 -43
- data/vendor/html-to-markdown-rs/src/converter/handlers/blockquote.rs +0 -173
- data/vendor/html-to-markdown-rs/src/converter/handlers/code_block.rs +0 -434
- data/vendor/html-to-markdown-rs/src/converter/handlers/graphic.rs +0 -234
- data/vendor/html-to-markdown-rs/src/converter/handlers/image.rs +0 -282
- data/vendor/html-to-markdown-rs/src/converter/handlers/link.rs +0 -316
- data/vendor/html-to-markdown-rs/src/converter/handlers/mod.rs +0 -26
- data/vendor/html-to-markdown-rs/src/converter/inline/code.rs +0 -306
- data/vendor/html-to-markdown-rs/src/converter/inline/emphasis.rs +0 -345
- data/vendor/html-to-markdown-rs/src/converter/inline/link.rs +0 -428
- data/vendor/html-to-markdown-rs/src/converter/inline/mod.rs +0 -237
- data/vendor/html-to-markdown-rs/src/converter/inline/ruby.rs +0 -337
- data/vendor/html-to-markdown-rs/src/converter/inline/semantic/marks.rs +0 -566
- data/vendor/html-to-markdown-rs/src/converter/inline/semantic/mod.rs +0 -86
- data/vendor/html-to-markdown-rs/src/converter/inline/semantic/typography.rs +0 -558
- data/vendor/html-to-markdown-rs/src/converter/list/definition.rs +0 -232
- data/vendor/html-to-markdown-rs/src/converter/list/item.rs +0 -332
- data/vendor/html-to-markdown-rs/src/converter/list/mod.rs +0 -70
- data/vendor/html-to-markdown-rs/src/converter/list/ordered.rs +0 -201
- data/vendor/html-to-markdown-rs/src/converter/list/unordered.rs +0 -195
- data/vendor/html-to-markdown-rs/src/converter/list/utils.rs +0 -314
- data/vendor/html-to-markdown-rs/src/converter/main.rs +0 -710
- data/vendor/html-to-markdown-rs/src/converter/main_helpers.rs +0 -452
- data/vendor/html-to-markdown-rs/src/converter/media/embedded.rs +0 -393
- data/vendor/html-to-markdown-rs/src/converter/media/graphic.rs +0 -4
- data/vendor/html-to-markdown-rs/src/converter/media/image.rs +0 -183
- data/vendor/html-to-markdown-rs/src/converter/media/mod.rs +0 -87
- data/vendor/html-to-markdown-rs/src/converter/media/svg.rs +0 -280
- data/vendor/html-to-markdown-rs/src/converter/metadata.rs +0 -220
- data/vendor/html-to-markdown-rs/src/converter/mod.rs +0 -156
- data/vendor/html-to-markdown-rs/src/converter/plain_text.rs +0 -516
- data/vendor/html-to-markdown-rs/src/converter/preprocessing_helpers.rs +0 -201
- data/vendor/html-to-markdown-rs/src/converter/reference_collector.rs +0 -69
- data/vendor/html-to-markdown-rs/src/converter/semantic/attributes.rs +0 -269
- data/vendor/html-to-markdown-rs/src/converter/semantic/definition_list.rs +0 -266
- data/vendor/html-to-markdown-rs/src/converter/semantic/figure.rs +0 -391
- data/vendor/html-to-markdown-rs/src/converter/semantic/mod.rs +0 -112
- data/vendor/html-to-markdown-rs/src/converter/semantic/sectioning.rs +0 -85
- data/vendor/html-to-markdown-rs/src/converter/semantic/summary.rs +0 -324
- data/vendor/html-to-markdown-rs/src/converter/text/mod.rs +0 -8
- data/vendor/html-to-markdown-rs/src/converter/text/processing.rs +0 -56
- data/vendor/html-to-markdown-rs/src/converter/text_node.rs +0 -269
- data/vendor/html-to-markdown-rs/src/converter/utility/attributes.rs +0 -151
- data/vendor/html-to-markdown-rs/src/converter/utility/caching.rs +0 -74
- data/vendor/html-to-markdown-rs/src/converter/utility/content.rs +0 -271
- data/vendor/html-to-markdown-rs/src/converter/utility/mod.rs +0 -17
- data/vendor/html-to-markdown-rs/src/converter/utility/preprocessing.rs +0 -1002
- data/vendor/html-to-markdown-rs/src/converter/utility/serialization.rs +0 -126
- data/vendor/html-to-markdown-rs/src/converter/utility/siblings.rs +0 -97
- data/vendor/html-to-markdown-rs/src/converter/visitor_hooks.rs +0 -189
- data/vendor/html-to-markdown-rs/src/error.rs +0 -43
- data/vendor/html-to-markdown-rs/src/exports.rs +0 -24
- data/vendor/html-to-markdown-rs/src/inline_images.rs +0 -336
- data/vendor/html-to-markdown-rs/src/lib.rs +0 -139
- data/vendor/html-to-markdown-rs/src/metadata/collector.rs +0 -457
- data/vendor/html-to-markdown-rs/src/metadata/config.rs +0 -394
- data/vendor/html-to-markdown-rs/src/metadata/extraction.rs +0 -398
- data/vendor/html-to-markdown-rs/src/metadata/mod.rs +0 -288
- data/vendor/html-to-markdown-rs/src/metadata/types.rs +0 -477
- data/vendor/html-to-markdown-rs/src/options/conversion.rs +0 -559
- data/vendor/html-to-markdown-rs/src/options/inline_image.rs +0 -111
- data/vendor/html-to-markdown-rs/src/options/mod.rs +0 -20
- data/vendor/html-to-markdown-rs/src/options/preprocessing.rs +0 -201
- data/vendor/html-to-markdown-rs/src/options/validation.rs +0 -416
- data/vendor/html-to-markdown-rs/src/prelude.rs +0 -1
- data/vendor/html-to-markdown-rs/src/rcdom.rs +0 -487
- data/vendor/html-to-markdown-rs/src/text.rs +0 -358
- data/vendor/html-to-markdown-rs/src/types/document.rs +0 -191
- data/vendor/html-to-markdown-rs/src/types/mod.rs +0 -17
- data/vendor/html-to-markdown-rs/src/types/result.rs +0 -54
- data/vendor/html-to-markdown-rs/src/types/structure_builder.rs +0 -791
- data/vendor/html-to-markdown-rs/src/types/structure_collector.rs +0 -483
- data/vendor/html-to-markdown-rs/src/types/tables.rs +0 -52
- data/vendor/html-to-markdown-rs/src/types/warnings.rs +0 -33
- data/vendor/html-to-markdown-rs/src/validation.rs +0 -158
- data/vendor/html-to-markdown-rs/src/visitor/default_impl.rs +0 -63
- data/vendor/html-to-markdown-rs/src/visitor/mod.rs +0 -41
- data/vendor/html-to-markdown-rs/src/visitor/traits.rs +0 -370
- data/vendor/html-to-markdown-rs/src/visitor/types.rs +0 -319
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/callbacks/mod.rs +0 -1
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/content.rs +0 -126
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/mod.rs +0 -27
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/state.rs +0 -110
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/traversal.rs +0 -250
- data/vendor/html-to-markdown-rs/src/visitor_helpers.rs +0 -597
- data/vendor/html-to-markdown-rs/src/wrapper/sync.rs +0 -413
- data/vendor/html-to-markdown-rs/src/wrapper/utils.rs +0 -290
- data/vendor/html-to-markdown-rs/src/wrapper.rs +0 -9
- data/vendor/html-to-markdown-rs/tests/br_in_inline_test.rs +0 -87
- data/vendor/html-to-markdown-rs/tests/commonmark_compliance_test.rs +0 -297
- data/vendor/html-to-markdown-rs/tests/djot_output_test.rs +0 -153
- data/vendor/html-to-markdown-rs/tests/exclude_selectors_test.rs +0 -132
- data/vendor/html-to-markdown-rs/tests/integration_test.rs +0 -631
- data/vendor/html-to-markdown-rs/tests/issue_121_regressions.rs +0 -49
- data/vendor/html-to-markdown-rs/tests/issue_127_regressions.rs +0 -58
- data/vendor/html-to-markdown-rs/tests/issue_128_regressions.rs +0 -17
- data/vendor/html-to-markdown-rs/tests/issue_131_regressions.rs +0 -41
- data/vendor/html-to-markdown-rs/tests/issue_134_regressions.rs +0 -40
- data/vendor/html-to-markdown-rs/tests/issue_139_regressions.rs +0 -26
- data/vendor/html-to-markdown-rs/tests/issue_140_regressions.rs +0 -185
- data/vendor/html-to-markdown-rs/tests/issue_143_regressions.rs +0 -100
- data/vendor/html-to-markdown-rs/tests/issue_145_regressions.rs +0 -133
- data/vendor/html-to-markdown-rs/tests/issue_146_regressions.rs +0 -144
- data/vendor/html-to-markdown-rs/tests/issue_176_regressions.rs +0 -62
- data/vendor/html-to-markdown-rs/tests/issue_190_regressions.rs +0 -128
- data/vendor/html-to-markdown-rs/tests/issue_199_regressions.rs +0 -20
- data/vendor/html-to-markdown-rs/tests/issue_200_regressions.rs +0 -62
- data/vendor/html-to-markdown-rs/tests/issue_212_regressions.rs +0 -68
- data/vendor/html-to-markdown-rs/tests/issue_216_217_regressions.rs +0 -87
- data/vendor/html-to-markdown-rs/tests/issue_336_regressions.rs +0 -74
- data/vendor/html-to-markdown-rs/tests/issue_339_regressions.rs +0 -92
- data/vendor/html-to-markdown-rs/tests/issue_347_regressions.rs +0 -154
- data/vendor/html-to-markdown-rs/tests/issue_348_visitor_plain.rs +0 -93
- data/vendor/html-to-markdown-rs/tests/json_ld_script_extraction.rs +0 -44
- data/vendor/html-to-markdown-rs/tests/lists_test.rs +0 -199
- data/vendor/html-to-markdown-rs/tests/plain_output_test.rs +0 -273
- data/vendor/html-to-markdown-rs/tests/preprocessing_tests.rs +0 -61
- data/vendor/html-to-markdown-rs/tests/reference_links_test.rs +0 -169
- data/vendor/html-to-markdown-rs/tests/sectioning_elements_test.rs +0 -137
- data/vendor/html-to-markdown-rs/tests/skip_images_test.rs +0 -522
- data/vendor/html-to-markdown-rs/tests/tables_test.rs +0 -743
- data/vendor/html-to-markdown-rs/tests/test_custom_elements.rs +0 -41
- data/vendor/html-to-markdown-rs/tests/test_issue_187.rs +0 -204
- data/vendor/html-to-markdown-rs/tests/test_issue_218.rs +0 -68
- data/vendor/html-to-markdown-rs/tests/test_issue_277.rs +0 -77
- data/vendor/html-to-markdown-rs/tests/test_max_depth.rs +0 -82
- data/vendor/html-to-markdown-rs/tests/test_nested_simple.rs +0 -45
- data/vendor/html-to-markdown-rs/tests/test_script_style_stripping.rs +0 -396
- data/vendor/html-to-markdown-rs/tests/test_spa_bisect.rs +0 -34
- data/vendor/html-to-markdown-rs/tests/visitor_code_integration_test.rs +0 -121
- data/vendor/html-to-markdown-rs/tests/visitor_integration_test.rs +0 -1190
- data/vendor/html-to-markdown-rs/tests/xml_tables_test.rs +0 -372
|
@@ -1,487 +0,0 @@
|
|
|
1
|
-
// Vendored from markup5ever_rcdom v0.36.0+unofficial
|
|
2
|
-
// Original source: https://github.com/servo/html5ever (rcdom/)
|
|
3
|
-
// Copyright (c) 2014 The html5ever Project Developers
|
|
4
|
-
// Licensed under MIT OR Apache-2.0 (see ATTRIBUTIONS.md)
|
|
5
|
-
//
|
|
6
|
-
// Vendored to:
|
|
7
|
-
// - Remove unused xml5ever transitive dependency
|
|
8
|
-
// - Eliminate pinned external dependency on "+unofficial" crate
|
|
9
|
-
// - Gain full control over this small, critical module
|
|
10
|
-
//
|
|
11
|
-
// Changes from upstream:
|
|
12
|
-
// - Replaced `extern crate markup5ever` / `extern crate tendril` with
|
|
13
|
-
// `use` imports through `html5ever` (edition 2024 compatibility)
|
|
14
|
-
// - Added module-level clippy allows for vendored code style
|
|
15
|
-
|
|
16
|
-
#![allow(
|
|
17
|
-
clippy::panic,
|
|
18
|
-
clippy::expect_used,
|
|
19
|
-
clippy::missing_panics_doc,
|
|
20
|
-
clippy::must_use_candidate,
|
|
21
|
-
clippy::return_self_not_must_use,
|
|
22
|
-
clippy::module_name_repetitions,
|
|
23
|
-
clippy::redundant_else,
|
|
24
|
-
clippy::match_wildcard_for_single_variants,
|
|
25
|
-
clippy::similar_names,
|
|
26
|
-
clippy::items_after_statements,
|
|
27
|
-
clippy::use_self,
|
|
28
|
-
clippy::missing_fields_in_debug,
|
|
29
|
-
clippy::semicolon_if_nothing_returned,
|
|
30
|
-
missing_docs
|
|
31
|
-
)]
|
|
32
|
-
|
|
33
|
-
//! A simple reference-counted DOM.
|
|
34
|
-
//!
|
|
35
|
-
//! This is sufficient as a static parse tree, but don't build a
|
|
36
|
-
//! web browser using it. :)
|
|
37
|
-
|
|
38
|
-
use std::borrow::Cow;
|
|
39
|
-
use std::cell::{Cell, RefCell};
|
|
40
|
-
use std::collections::{HashSet, VecDeque};
|
|
41
|
-
use std::default::Default;
|
|
42
|
-
use std::fmt;
|
|
43
|
-
use std::io;
|
|
44
|
-
use std::mem;
|
|
45
|
-
use std::rc::{Rc, Weak};
|
|
46
|
-
|
|
47
|
-
use html5ever::tendril::StrTendril;
|
|
48
|
-
|
|
49
|
-
use html5ever::Attribute;
|
|
50
|
-
use html5ever::ExpandedName;
|
|
51
|
-
use html5ever::QualName;
|
|
52
|
-
use html5ever::interface::tree_builder;
|
|
53
|
-
use html5ever::interface::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink};
|
|
54
|
-
use html5ever::serialize::TraversalScope;
|
|
55
|
-
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
|
56
|
-
use html5ever::serialize::{Serialize, Serializer};
|
|
57
|
-
|
|
58
|
-
/// The different kinds of nodes in the DOM.
|
|
59
|
-
#[derive(Debug)]
|
|
60
|
-
pub enum NodeData {
|
|
61
|
-
/// The `Document` itself - the root node of a HTML document.
|
|
62
|
-
Document,
|
|
63
|
-
|
|
64
|
-
/// A `DOCTYPE` with name, public id, and system id. See
|
|
65
|
-
/// [document type declaration on wikipedia][dtd wiki].
|
|
66
|
-
///
|
|
67
|
-
/// [dtd wiki]: https://en.wikipedia.org/wiki/Document_type_declaration
|
|
68
|
-
Doctype {
|
|
69
|
-
name: StrTendril,
|
|
70
|
-
// Fields required by html5ever's DOM model; not accessed during conversion.
|
|
71
|
-
#[allow(dead_code)]
|
|
72
|
-
public_id: StrTendril,
|
|
73
|
-
#[allow(dead_code)]
|
|
74
|
-
system_id: StrTendril,
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
/// A text node.
|
|
78
|
-
Text { contents: RefCell<StrTendril> },
|
|
79
|
-
|
|
80
|
-
/// A comment.
|
|
81
|
-
Comment { contents: StrTendril },
|
|
82
|
-
|
|
83
|
-
/// An element with attributes.
|
|
84
|
-
Element {
|
|
85
|
-
name: QualName,
|
|
86
|
-
attrs: RefCell<Vec<Attribute>>,
|
|
87
|
-
|
|
88
|
-
/// For HTML \<template\> elements, the [template contents].
|
|
89
|
-
///
|
|
90
|
-
/// [template contents]: https://html.spec.whatwg.org/multipage/#template-contents
|
|
91
|
-
template_contents: RefCell<Option<Handle>>,
|
|
92
|
-
|
|
93
|
-
/// Whether the node is a [HTML integration point].
|
|
94
|
-
///
|
|
95
|
-
/// [HTML integration point]: https://html.spec.whatwg.org/multipage/#html-integration-point
|
|
96
|
-
mathml_annotation_xml_integration_point: bool,
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
/// A Processing instruction.
|
|
100
|
-
ProcessingInstruction { target: StrTendril, contents: StrTendril },
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/// A DOM node.
|
|
104
|
-
pub struct Node {
|
|
105
|
-
/// Parent node.
|
|
106
|
-
pub parent: Cell<Option<WeakHandle>>,
|
|
107
|
-
/// Child nodes of this node.
|
|
108
|
-
pub children: RefCell<Vec<Handle>>,
|
|
109
|
-
/// Represents this node's data.
|
|
110
|
-
pub data: NodeData,
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
impl Node {
|
|
114
|
-
/// Create a new node from its contents
|
|
115
|
-
pub fn new(data: NodeData) -> Rc<Self> {
|
|
116
|
-
Rc::new(Node {
|
|
117
|
-
data,
|
|
118
|
-
parent: Cell::new(None),
|
|
119
|
-
children: RefCell::new(Vec::new()),
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
impl Drop for Node {
|
|
125
|
-
fn drop(&mut self) {
|
|
126
|
-
let mut nodes = mem::take(&mut *self.children.borrow_mut());
|
|
127
|
-
while let Some(node) = nodes.pop() {
|
|
128
|
-
let children = mem::take(&mut *node.children.borrow_mut());
|
|
129
|
-
nodes.extend(children);
|
|
130
|
-
if let NodeData::Element {
|
|
131
|
-
ref template_contents, ..
|
|
132
|
-
} = node.data
|
|
133
|
-
{
|
|
134
|
-
if let Some(template_contents) = template_contents.borrow_mut().take() {
|
|
135
|
-
nodes.push(template_contents);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
impl fmt::Debug for Node {
|
|
143
|
-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
144
|
-
fmt.debug_struct("Node")
|
|
145
|
-
.field("data", &self.data)
|
|
146
|
-
.field("children", &self.children)
|
|
147
|
-
.finish()
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/// Reference to a DOM node.
|
|
152
|
-
pub type Handle = Rc<Node>;
|
|
153
|
-
|
|
154
|
-
/// Weak reference to a DOM node, used for parent pointers.
|
|
155
|
-
pub type WeakHandle = Weak<Node>;
|
|
156
|
-
|
|
157
|
-
/// Append a parentless node to another nodes' children
|
|
158
|
-
fn append(new_parent: &Handle, child: Handle) {
|
|
159
|
-
let previous_parent = child.parent.replace(Some(Rc::downgrade(new_parent)));
|
|
160
|
-
// Invariant: child cannot have existing parent
|
|
161
|
-
assert!(previous_parent.is_none());
|
|
162
|
-
new_parent.children.borrow_mut().push(child);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/// If the node has a parent, get it and this node's position in its children
|
|
166
|
-
fn get_parent_and_index(target: &Handle) -> Option<(Handle, usize)> {
|
|
167
|
-
if let Some(weak) = target.parent.take() {
|
|
168
|
-
let parent = weak.upgrade().expect("dangling weak pointer");
|
|
169
|
-
target.parent.set(Some(weak));
|
|
170
|
-
let i = match parent
|
|
171
|
-
.children
|
|
172
|
-
.borrow()
|
|
173
|
-
.iter()
|
|
174
|
-
.enumerate()
|
|
175
|
-
.find(|&(_, child)| Rc::ptr_eq(child, target))
|
|
176
|
-
{
|
|
177
|
-
Some((i, _)) => i,
|
|
178
|
-
None => panic!("have parent but couldn't find in parent's children!"),
|
|
179
|
-
};
|
|
180
|
-
Some((parent, i))
|
|
181
|
-
} else {
|
|
182
|
-
None
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
fn append_to_existing_text(prev: &Handle, text: &str) -> bool {
|
|
187
|
-
match prev.data {
|
|
188
|
-
NodeData::Text { ref contents } => {
|
|
189
|
-
contents.borrow_mut().push_slice(text);
|
|
190
|
-
true
|
|
191
|
-
}
|
|
192
|
-
_ => false,
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
fn remove_from_parent(target: &Handle) {
|
|
197
|
-
if let Some((parent, i)) = get_parent_and_index(target) {
|
|
198
|
-
parent.children.borrow_mut().remove(i);
|
|
199
|
-
target.parent.set(None);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/// The DOM itself; the result of parsing.
|
|
204
|
-
pub struct RcDom {
|
|
205
|
-
/// The `Document` itself.
|
|
206
|
-
pub document: Handle,
|
|
207
|
-
|
|
208
|
-
/// Errors that occurred during parsing.
|
|
209
|
-
pub errors: RefCell<Vec<Cow<'static, str>>>,
|
|
210
|
-
|
|
211
|
-
/// The document's quirks mode.
|
|
212
|
-
pub quirks_mode: Cell<QuirksMode>,
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
impl TreeSink for RcDom {
|
|
216
|
-
type Output = Self;
|
|
217
|
-
fn finish(self) -> Self {
|
|
218
|
-
self
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
type Handle = Handle;
|
|
222
|
-
|
|
223
|
-
type ElemName<'a>
|
|
224
|
-
= ExpandedName<'a>
|
|
225
|
-
where
|
|
226
|
-
Self: 'a;
|
|
227
|
-
|
|
228
|
-
fn parse_error(&self, msg: Cow<'static, str>) {
|
|
229
|
-
self.errors.borrow_mut().push(msg);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
fn get_document(&self) -> Handle {
|
|
233
|
-
self.document.clone()
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
fn get_template_contents(&self, target: &Handle) -> Handle {
|
|
237
|
-
if let NodeData::Element {
|
|
238
|
-
ref template_contents, ..
|
|
239
|
-
} = target.data
|
|
240
|
-
{
|
|
241
|
-
template_contents
|
|
242
|
-
.borrow()
|
|
243
|
-
.as_ref()
|
|
244
|
-
.expect("not a template element!")
|
|
245
|
-
.clone()
|
|
246
|
-
} else {
|
|
247
|
-
panic!("not a template element!")
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
fn set_quirks_mode(&self, mode: QuirksMode) {
|
|
252
|
-
self.quirks_mode.set(mode);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
fn same_node(&self, x: &Handle, y: &Handle) -> bool {
|
|
256
|
-
Rc::ptr_eq(x, y)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
fn elem_name<'a>(&self, target: &'a Handle) -> ExpandedName<'a> {
|
|
260
|
-
match target.data {
|
|
261
|
-
NodeData::Element { ref name, .. } => name.expanded(),
|
|
262
|
-
_ => panic!("not an element!"),
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
fn create_element(&self, name: QualName, attrs: Vec<Attribute>, flags: ElementFlags) -> Handle {
|
|
267
|
-
Node::new(NodeData::Element {
|
|
268
|
-
name,
|
|
269
|
-
attrs: RefCell::new(attrs),
|
|
270
|
-
template_contents: RefCell::new(if flags.template {
|
|
271
|
-
Some(Node::new(NodeData::Document))
|
|
272
|
-
} else {
|
|
273
|
-
None
|
|
274
|
-
}),
|
|
275
|
-
mathml_annotation_xml_integration_point: flags.mathml_annotation_xml_integration_point,
|
|
276
|
-
})
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
fn create_comment(&self, text: StrTendril) -> Handle {
|
|
280
|
-
Node::new(NodeData::Comment { contents: text })
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
fn create_pi(&self, target: StrTendril, data: StrTendril) -> Handle {
|
|
284
|
-
Node::new(NodeData::ProcessingInstruction { target, contents: data })
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
fn append(&self, parent: &Handle, child: NodeOrText<Handle>) {
|
|
288
|
-
// Append to an existing Text node if we have one.
|
|
289
|
-
if let NodeOrText::AppendText(text) = &child {
|
|
290
|
-
if let Some(h) = parent.children.borrow().last() {
|
|
291
|
-
if append_to_existing_text(h, text) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
append(
|
|
298
|
-
parent,
|
|
299
|
-
match child {
|
|
300
|
-
NodeOrText::AppendText(text) => Node::new(NodeData::Text {
|
|
301
|
-
contents: RefCell::new(text),
|
|
302
|
-
}),
|
|
303
|
-
NodeOrText::AppendNode(node) => node,
|
|
304
|
-
},
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
fn append_before_sibling(&self, sibling: &Handle, child: NodeOrText<Handle>) {
|
|
309
|
-
let (parent, i) = get_parent_and_index(sibling).expect("append_before_sibling called on node without parent");
|
|
310
|
-
|
|
311
|
-
let child = match (child, i) {
|
|
312
|
-
// No previous node.
|
|
313
|
-
(NodeOrText::AppendText(text), 0) => Node::new(NodeData::Text {
|
|
314
|
-
contents: RefCell::new(text),
|
|
315
|
-
}),
|
|
316
|
-
|
|
317
|
-
// Look for a text node before the insertion point.
|
|
318
|
-
(NodeOrText::AppendText(text), i) => {
|
|
319
|
-
let children = parent.children.borrow();
|
|
320
|
-
let prev = &children[i - 1];
|
|
321
|
-
if append_to_existing_text(prev, &text) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
Node::new(NodeData::Text {
|
|
325
|
-
contents: RefCell::new(text),
|
|
326
|
-
})
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// The tree builder promises we won't have a text node after
|
|
330
|
-
// the insertion point.
|
|
331
|
-
|
|
332
|
-
// Any other kind of node.
|
|
333
|
-
(NodeOrText::AppendNode(node), _) => node,
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
remove_from_parent(&child);
|
|
337
|
-
|
|
338
|
-
child.parent.set(Some(Rc::downgrade(&parent)));
|
|
339
|
-
parent.children.borrow_mut().insert(i, child);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
fn append_based_on_parent_node(
|
|
343
|
-
&self,
|
|
344
|
-
element: &Self::Handle,
|
|
345
|
-
prev_element: &Self::Handle,
|
|
346
|
-
child: NodeOrText<Self::Handle>,
|
|
347
|
-
) {
|
|
348
|
-
let parent = element.parent.take();
|
|
349
|
-
let has_parent = parent.is_some();
|
|
350
|
-
element.parent.set(parent);
|
|
351
|
-
|
|
352
|
-
if has_parent {
|
|
353
|
-
self.append_before_sibling(element, child);
|
|
354
|
-
} else {
|
|
355
|
-
self.append(prev_element, child);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
fn append_doctype_to_document(&self, name: StrTendril, public_id: StrTendril, system_id: StrTendril) {
|
|
360
|
-
append(
|
|
361
|
-
&self.document,
|
|
362
|
-
Node::new(NodeData::Doctype {
|
|
363
|
-
name,
|
|
364
|
-
public_id,
|
|
365
|
-
system_id,
|
|
366
|
-
}),
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
fn add_attrs_if_missing(&self, target: &Handle, attrs: Vec<Attribute>) {
|
|
371
|
-
let mut existing = if let NodeData::Element { ref attrs, .. } = target.data {
|
|
372
|
-
attrs.borrow_mut()
|
|
373
|
-
} else {
|
|
374
|
-
panic!("not an element")
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
let existing_names = existing.iter().map(|e| e.name.clone()).collect::<HashSet<_>>();
|
|
378
|
-
existing.extend(attrs.into_iter().filter(|attr| !existing_names.contains(&attr.name)));
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
fn remove_from_parent(&self, target: &Handle) {
|
|
382
|
-
remove_from_parent(target);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
fn reparent_children(&self, node: &Handle, new_parent: &Handle) {
|
|
386
|
-
let mut children = node.children.borrow_mut();
|
|
387
|
-
let mut new_children = new_parent.children.borrow_mut();
|
|
388
|
-
for child in children.iter() {
|
|
389
|
-
let previous_parent = child.parent.replace(Some(Rc::downgrade(new_parent)));
|
|
390
|
-
assert!(Rc::ptr_eq(
|
|
391
|
-
node,
|
|
392
|
-
&previous_parent
|
|
393
|
-
.expect("invariant: child must have a parent during reparenting")
|
|
394
|
-
.upgrade()
|
|
395
|
-
.expect("dangling weak")
|
|
396
|
-
))
|
|
397
|
-
}
|
|
398
|
-
new_children.extend(mem::take(&mut *children));
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
fn is_mathml_annotation_xml_integration_point(&self, target: &Handle) -> bool {
|
|
402
|
-
if let NodeData::Element {
|
|
403
|
-
mathml_annotation_xml_integration_point,
|
|
404
|
-
..
|
|
405
|
-
} = target.data
|
|
406
|
-
{
|
|
407
|
-
mathml_annotation_xml_integration_point
|
|
408
|
-
} else {
|
|
409
|
-
panic!("not an element!")
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
impl Default for RcDom {
|
|
415
|
-
fn default() -> RcDom {
|
|
416
|
-
RcDom {
|
|
417
|
-
document: Node::new(NodeData::Document),
|
|
418
|
-
errors: Default::default(),
|
|
419
|
-
quirks_mode: Cell::new(tree_builder::NoQuirks),
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
enum SerializeOp {
|
|
425
|
-
Open(Handle),
|
|
426
|
-
Close(QualName),
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
pub struct SerializableHandle(Handle);
|
|
430
|
-
|
|
431
|
-
impl From<Handle> for SerializableHandle {
|
|
432
|
-
fn from(h: Handle) -> SerializableHandle {
|
|
433
|
-
SerializableHandle(h)
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
impl Serialize for SerializableHandle {
|
|
438
|
-
fn serialize<S>(&self, serializer: &mut S, traversal_scope: TraversalScope) -> io::Result<()>
|
|
439
|
-
where
|
|
440
|
-
S: Serializer,
|
|
441
|
-
{
|
|
442
|
-
let mut ops = VecDeque::new();
|
|
443
|
-
match traversal_scope {
|
|
444
|
-
IncludeNode => ops.push_back(SerializeOp::Open(self.0.clone())),
|
|
445
|
-
ChildrenOnly(_) => ops.extend(self.0.children.borrow().iter().map(|h| SerializeOp::Open(h.clone()))),
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
while let Some(op) = ops.pop_front() {
|
|
449
|
-
match op {
|
|
450
|
-
SerializeOp::Open(handle) => match handle.data {
|
|
451
|
-
NodeData::Element {
|
|
452
|
-
ref name, ref attrs, ..
|
|
453
|
-
} => {
|
|
454
|
-
serializer
|
|
455
|
-
.start_elem(name.clone(), attrs.borrow().iter().map(|at| (&at.name, &at.value[..])))?;
|
|
456
|
-
|
|
457
|
-
ops.reserve(1 + handle.children.borrow().len());
|
|
458
|
-
ops.push_front(SerializeOp::Close(name.clone()));
|
|
459
|
-
|
|
460
|
-
for child in handle.children.borrow().iter().rev() {
|
|
461
|
-
ops.push_front(SerializeOp::Open(child.clone()));
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
NodeData::Doctype { ref name, .. } => serializer.write_doctype(name)?,
|
|
466
|
-
|
|
467
|
-
NodeData::Text { ref contents } => serializer.write_text(&contents.borrow())?,
|
|
468
|
-
|
|
469
|
-
NodeData::Comment { ref contents } => serializer.write_comment(contents)?,
|
|
470
|
-
|
|
471
|
-
NodeData::ProcessingInstruction {
|
|
472
|
-
ref target,
|
|
473
|
-
ref contents,
|
|
474
|
-
} => serializer.write_processing_instruction(target, contents)?,
|
|
475
|
-
|
|
476
|
-
NodeData::Document => panic!("Can't serialize Document node itself"),
|
|
477
|
-
},
|
|
478
|
-
|
|
479
|
-
SerializeOp::Close(name) => {
|
|
480
|
-
serializer.end_elem(name)?;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
Ok(())
|
|
486
|
-
}
|
|
487
|
-
}
|