1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Fast, type-safe HTML generation for Rust and WebAssembly.
//!
//! A composite tree of plain values, escaped by default and rendered compact or pretty,
//! compiled to native code or to `wasm32-unknown-unknown`.
//!
//! # Getting started
//!
//! ```
//! use molt::prelude::*;
//!
//! let card = article()
//! .add_class("card p-4")
//! .child(h1().text("Welcome to Molt!").add_class("text-2xl"))
//! .child(p().text("Ultra-fast HTML generation compiled to WebAssembly."));
//!
//! println!("{}", card.render_pretty());
//! ```
//!
//! # Escaping
//!
//! Text content and attribute values are escaped **when they enter the tree**, not when it
//! is rendered, so nothing is escaped twice and nothing is missed. [`Node::Raw`] is the
//! documented way to inject markup you already trust.
//!
//! URL attributes (`href`, `src`, `action`, `srcset`, … — the list is in
//! [`core::url_policy`]) are checked **when the tree is written**: a `javascript:` or
//! `vbscript:` URL, or `data:text/html`, renders as `#`, and so does a `data:` document in
//! an `iframe`, `frame`, `embed` or `object`. The check also covers a value stored with
//! [`Attribute::raw`](core::Attribute::raw), and `srcdoc` is written empty.
//! [`Element::trusted_url`] opts out for a URL you wrote yourself. Tag and attribute names
//! are validated too. See `SECURITY.md`.
//!
//! ```
//! use molt::prelude::*;
//! assert_eq!(p().text("<script>").render(), "<p><script></p>");
//! ```
//!
//! # Render modes
//!
//! [`Render::render`] produces a single line; [`Render::render_pretty`] indents. Both take
//! their configuration from a [`RenderOptions`] value rather than global state, so two
//! threads can render the same tree differently at the same time.
//!
//! # Limits
//!
//! Rendering has no depth limit by default: the writer walks an explicit stack instead of
//! recursing, and so do `Clone`, `PartialEq`, `Hash` and `Drop`. What deep trees do cost is
//! output size in pretty mode, which is quadratic in depth because every line carries one
//! indent string per level. When depth comes from untrusted input, bound it with
//! [`RenderOptions::with_max_depth`]. See [`Render`] and `SECURITY.md`.
//!
//! # Golden fixtures
//!
//! The rendered markup of a whole page, a sitemap and a feed is compared byte for byte with
//! files in `tests/fixtures/`, so a change to the output of valid input cannot go unnoticed.
//! `MIGRATION.md` lists what changed between releases.
// The logo and favicon shown by rustdoc (docs.rs and the Pages build). The file lives at the
// repository root and is excluded from the package, so the URL has to be absolute.
pub use crate;
pub use crateDocument;
pub use crateLayout;
/// The prose guides are doc tests too, so a snippet in them cannot rot. Gated on `ssg`
/// because both use `molt::ssg`, and on not being `wasm32`, because there the module does not
/// exist even with the feature on (`wasm-pack test` runs the doc tests for that target).
/// Compiled only when running doc tests.