Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ElementContentHandlers and DocumentContentHandlers fields public. #194

Merged
merged 3 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/base/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ use std::cell::Cell;
use std::ops::Deref;
use std::rc::Rc;

/// A charset encoding that can be shared and modified.
///
/// This is, for instance, used to adapt the charset dynamically in a [crate::HtmlRewriter] if it
/// encounters a `meta` tag that specifies the charset (that behavior is dependent on
/// [crate::Settings::adjust_charset_on_meta_tag]).
#[derive(Clone)]
pub struct SharedEncoding {
encoding: Rc<Cell<AsciiCompatibleEncoding>>,
Expand Down
9 changes: 6 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
//! [`HtmlRewriter`]: struct.HtmlRewriter.html
//! [`rewrite_str`]: fn.rewrite_str.html

// TODO Uncomment this once we have all items documented.
// #![cfg_attr(not(any(feature = "integration_test", test)), warn(missing_docs))]

#[macro_use]
mod base;

Expand All @@ -34,8 +37,9 @@ mod transform_stream;
use cfg_if::cfg_if;

pub use self::rewriter::{
rewrite_str, AsciiCompatibleEncoding, DocumentContentHandlers, ElementContentHandlers,
HtmlRewriter, MemorySettings, RewriteStrSettings, Settings,
rewrite_str, AsciiCompatibleEncoding, CommentHandler, DoctypeHandler, DocumentContentHandlers,
ElementContentHandlers, ElementHandler, EndHandler, EndTagHandler, HandlerResult, HtmlRewriter,
MemorySettings, RewriteStrSettings, Settings, TextHandler,
};
pub use self::selectors_vm::Selector;
pub use self::transform_stream::OutputSink;
Expand Down Expand Up @@ -165,7 +169,6 @@ cfg_if! {
EndTag, Serialize, StartTag, Token, TokenCaptureFlags, Mutations
};

pub use self::base::Bytes;
pub use self::memory::MemoryLimiter;
pub use self::html::{LocalName, LocalNameHash, Tag, Namespace};
} else {
Expand Down
9 changes: 9 additions & 0 deletions src/rewritable_units/tokens/end_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,25 @@ impl<'i> EndTag<'i> {
self.set_name(Bytes::from_string(name, self.encoding))
}

/// Inserts `content` before the end tag.
///
/// Consequent calls to the method append `content` to the previously inserted content.
#[inline]
pub fn before(&mut self, content: &str, content_type: ContentType) {
self.mutations.before(content, content_type);
}

/// Inserts `content` after the end tag.
///
/// Consequent calls to the method prepend `content` to the previously inserted content.
#[inline]
pub fn after(&mut self, content: &str, content_type: ContentType) {
self.mutations.after(content, content_type);
}

/// Replaces the end tag with `content`.
///
/// Consequent calls to the method overwrite previous replacement content.
#[inline]
pub fn replace(&mut self, content: &str, content_type: ContentType) {
self.mutations.replace(content, content_type);
Expand Down
9 changes: 9 additions & 0 deletions src/rewritable_units/tokens/start_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,25 @@ impl<'i> StartTag<'i> {
self.self_closing
}

/// Inserts `content` before the start tag.
///
/// Consequent calls to the method append `content` to the previously inserted content.
#[inline]
pub fn before(&mut self, content: &str, content_type: ContentType) {
self.mutations.before(content, content_type);
}

/// Inserts `content` after the start tag.
///
/// Consequent calls to the method prepend `content` to the previously inserted content.
#[inline]
pub fn after(&mut self, content: &str, content_type: ContentType) {
self.mutations.after(content, content_type);
}

/// Replaces the start tag with `content`.
///
/// Consequent calls to the method overwrite previous replacement content.
#[inline]
pub fn replace(&mut self, content: &str, content_type: ContentType) {
self.mutations.replace(content, content_type);
Expand Down
6 changes: 5 additions & 1 deletion src/rewritable_units/tokens/text_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,11 @@ mod tests {
use super::super::Token;

let encoding = Encoding::for_label_no_replacement("utf-8".as_bytes()).unwrap();
let Token::TextChunk(mut chunk) = TextChunk::new_token("original text", TextType::PlainText, true, encoding) else { unreachable!() };
let Token::TextChunk(mut chunk) =
TextChunk::new_token("original text", TextType::PlainText, true, encoding)
else {
unreachable!()
};

assert_eq!(chunk.as_str(), "original text");
chunk.set_str("hello".to_owned());
Expand Down
32 changes: 24 additions & 8 deletions src/rewriter/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,32 @@ use super::AsciiCompatibleEncoding;
use std::borrow::Cow;
use std::error::Error;

pub(crate) type HandlerResult = Result<(), Box<dyn Error + Send + Sync>>;
/// The result of a handler.
pub type HandlerResult = Result<(), Box<dyn Error + Send + Sync>>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need doc comments for those and all the newly exposed API. Let's add #![warn(missing_docs)] to the crate's lib.rs and also use `RUSTFLAGS="-D warnings" to the CI builds (if we don't have it already) to fail on missing docs

Copy link
Member Author

@orium orium Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add documentation to those fields. However, we can't fail on missing documentation right because it is missing from a lot of places:

warning: `lol_html` (lib) generated 21 warnings

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's revisit those and suppress the warning where it's intentional or provide docs otherwise.

/// Handler for the [document type declaration].
///
/// [document type declaration]: https://developer.mozilla.org/en-US/docs/Glossary/Doctype
pub type DoctypeHandler<'h> = Box<dyn FnMut(&mut Doctype) -> HandlerResult + 'h>;
/// Handler for HTML comments.
pub type CommentHandler<'h> = Box<dyn FnMut(&mut Comment) -> HandlerResult + 'h>;
/// Handler for text chunks present the HTML.
pub type TextHandler<'h> = Box<dyn FnMut(&mut TextChunk) -> HandlerResult + 'h>;
/// Handler for elements matched by a selector.
pub type ElementHandler<'h> = Box<dyn FnMut(&mut Element) -> HandlerResult + 'h>;
/// Handler for an end tag.
pub type EndTagHandler<'h> = Box<dyn FnOnce(&mut EndTag) -> HandlerResult + 'h>;
/// Handler for the document end, which is called after the last chunk is processed.
pub type EndHandler<'h> = Box<dyn FnOnce(&mut DocumentEnd) -> HandlerResult + 'h>;

/// Specifies element content handlers associated with a selector.
#[derive(Default)]
pub struct ElementContentHandlers<'h> {
pub(super) element: Option<ElementHandler<'h>>,
pub(super) comments: Option<CommentHandler<'h>>,
pub(super) text: Option<TextHandler<'h>>,
/// Element handler. See [ElementHandler].
pub element: Option<ElementHandler<'h>>,
/// Comment handler. See [CommentHandler].
pub comments: Option<CommentHandler<'h>>,
/// Text handler. See [TextHandler].
pub text: Option<TextHandler<'h>>,
}

impl<'h> ElementContentHandlers<'h> {
Expand Down Expand Up @@ -64,10 +76,14 @@ impl<'h> ElementContentHandlers<'h> {
/// ```
#[derive(Default)]
pub struct DocumentContentHandlers<'h> {
pub(super) doctype: Option<DoctypeHandler<'h>>,
pub(super) comments: Option<CommentHandler<'h>>,
pub(super) text: Option<TextHandler<'h>>,
pub(super) end: Option<EndHandler<'h>>,
/// Doctype handler. See [DoctypeHandler].
pub doctype: Option<DoctypeHandler<'h>>,
/// Comment handler. See [CommentHandler].
pub comments: Option<CommentHandler<'h>>,
/// Text handler. See [TextHandler].
pub text: Option<TextHandler<'h>>,
/// End handler. See [EndHandler].
pub end: Option<EndHandler<'h>>,
}

impl<'h> DocumentContentHandlers<'h> {
Expand Down
17 changes: 8 additions & 9 deletions src/selectors_vm/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,55 +989,54 @@ mod tests {
}

{
let (jumps, hereditary_jumps) = exec!("<div>", program.entry_points, vec![]);
let (jumps, hereditary_jumps) = exec!("<div>", program.entry_points, []);

assert_eq!(jumps.len(), 1);
assert_eq!(hereditary_jumps.len(), 1);

{
let (jumps, hereditary_jumps) = exec!("<span class='c1 c2'>", jumps[0], vec![0, 1]);
let (jumps, hereditary_jumps) = exec!("<span class='c1 c2'>", jumps[0], [0, 1]);

assert_eq!(jumps.len(), 0);
assert_eq!(hereditary_jumps.len(), 0);
}

{
let (jumps, hereditary_jumps) = exec!("<span class='c2'>", jumps[0], vec![1]);
let (jumps, hereditary_jumps) = exec!("<span class='c2'>", jumps[0], [1]);

assert_eq!(jumps.len(), 0);
assert_eq!(hereditary_jumps.len(), 0);
}

{
let (jumps, hereditary_jumps) = exec!("<h1 id=d2>", hereditary_jumps[0], vec![3]);
let (jumps, hereditary_jumps) = exec!("<h1 id=d2>", hereditary_jumps[0], [3]);

assert_eq!(jumps.len(), 0);
assert_eq!(hereditary_jumps.len(), 0);
}
}

{
let (jumps, hereditary_jumps) = exec!("<div foo=bar>", program.entry_points, vec![]);
let (jumps, hereditary_jumps) = exec!("<div foo=bar>", program.entry_points, []);

assert_eq!(jumps.len(), 1);
assert_eq!(hereditary_jumps.len(), 2);
}

{
let (jumps, hereditary_jumps) = exec!("<span foo=bar>", program.entry_points, vec![]);
let (jumps, hereditary_jumps) = exec!("<span foo=bar>", program.entry_points, []);

assert_eq!(jumps.len(), 0);
assert_eq!(hereditary_jumps.len(), 1);

{
let (jumps, hereditary_jumps) =
exec!("<table id=id1>", hereditary_jumps[0], vec![]);
let (jumps, hereditary_jumps) = exec!("<table id=id1>", hereditary_jumps[0], []);

assert_eq!(jumps.len(), 1);
assert_eq!(hereditary_jumps.len(), 0);

{
let (jumps, hereditary_jumps) = exec!("<span id=id2>", jumps[0], vec![4]);
let (jumps, hereditary_jumps) = exec!("<span id=id2>", jumps[0], [4]);

assert_eq!(jumps.len(), 0);
assert_eq!(hereditary_jumps.len(), 0);
Expand Down
Loading