Skip to content
Open
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
15 changes: 10 additions & 5 deletions src/annotate_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ mod tests {
// before and after the attributes table, to demonstrate that this is
// not sensitive to which order they occur in (i.e., these could be
// reordered in the HTML spec).
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<h3>The a element</h3>
Expand All @@ -333,6 +333,7 @@ mod tests {
<dd><code data-x="attr-area-href">href</code>
</dl>
"#.trim().as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand Down Expand Up @@ -368,7 +369,7 @@ mod tests {
async fn test_variant() -> io::Result<()> {
// This checks that <!-- variant --> and <!-- or: --> work correctly.
// i.e., the variant description is used where requested
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<h3>The a element</h3>
Expand All @@ -386,6 +387,7 @@ mod tests {
<dd><code data-x="attr-area-href">href</code><!-- variant -->
</dl>
"#.trim().as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand Down Expand Up @@ -415,7 +417,7 @@ mod tests {
#[tokio::test]
async fn test_special_semantics() -> io::Result<()> {
// Checks that the special rules for using : instead of an em dash work.
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<h3>The a element</h3>
Expand All @@ -428,6 +430,7 @@ mod tests {
<tr><th><code data-x>name</code><td><code data-x="attr-a-name">a</code><td>Anchor name
</tbody></table>
"#.trim().as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand All @@ -451,7 +454,7 @@ mod tests {
#[tokio::test]
async fn test_special_semantics_multiple() -> io::Result<()> {
// Checks that the special rules for joining any special semantics with a ; work.
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<h3>The a element</h3>
Expand All @@ -465,6 +468,7 @@ mod tests {
<tr><th><code data-x>name</code><td><code data-x="attr-a-name">a</code><td>Name of the anchor
</tbody></table>
"#.trim().as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand All @@ -490,7 +494,7 @@ mod tests {
async fn test_identical_links() -> io::Result<()> {
// This checks the same identifier can be linked multiple times without
// repeating the description.
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<h3>The img element</h3>
Expand All @@ -508,6 +512,7 @@ mod tests {
<tr><th><code data-x>width</code><td><code data-x="attr-dim-width">img</code>; <code data-x="attr-dim-width">video</code><td>Horizontal dimension
</tbody></table>
"#.trim().as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand Down
12 changes: 8 additions & 4 deletions src/boilerplate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,11 @@ mod tests {
"<tr><td>en<td>English",
)
.await?;
let document = parse_document_async(
let parsed = parse_document_async(
"<!DOCTYPE html><table><!--BOILERPLATE languages--></table>".as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new(boilerplate_dir.path(), Path::new("."));
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand All @@ -188,10 +189,11 @@ mod tests {
"data:text/html,Hello, world!",
)
.await?;
let document = parse_document_async(
let parsed = parse_document_async(
"<!DOCTYPE html><a href=\"<!--BOILERPLATE data.url-->\">hello</a>".as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new(boilerplate_dir.path(), Path::new("."));
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand All @@ -208,9 +210,10 @@ mod tests {
tokio::fs::write(example_dir.path().join("ex1"), "first").await?;
tokio::fs::write(example_dir.path().join("ex2"), "second").await?;
tokio::fs::write(example_dir.path().join("ignored"), "bad").await?;
let document =
let parsed =
parse_document_async("<!DOCTYPE html><pre>EXAMPLE ex1</pre><pre><code class=html>\nEXAMPLE ex2 </code></pre><p>EXAMPLE ignored</p>".as_bytes())
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new(Path::new("."), example_dir.path());
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply().await?;
Expand All @@ -229,7 +232,8 @@ mod tests {
"<!DOCTYPE html><body><pre>EXAMPLE ../foo</pre>",
];
for example in bad_path_examples {
let document = parse_document_async(example.as_bytes()).await?;
let parsed = parse_document_async(example.as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new(Path::new("."), Path::new("."));
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
let result = proc.apply().await;
Expand Down
13 changes: 13 additions & 0 deletions src/dom_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ pub trait NodeHandleExt {
/// Sets an attribute on the element. Must be an element.
fn set_attribute(&self, name: &QualName, value: StrTendril);

/// Removes an attribute from the element, if present. Must be an element.
fn remove_attribute(&self, name: &QualName);

/// Returns true if the node is an element.
fn is_element(&self) -> bool;

Expand Down Expand Up @@ -220,6 +223,16 @@ impl NodeHandleExt for Handle {
}
}

fn remove_attribute(&self, name: &QualName) {
let mut attrs = match self.data {
NodeData::Element { ref attrs, .. } => attrs.borrow_mut(),
_ => panic!("not an element"),
};
if let Some(i) = attrs.iter().position(|a| &a.name == name) {
attrs.remove(i);
}
}

fn is_element(&self) -> bool {
matches!(&self.data, NodeData::Element { .. })
}
Expand Down
27 changes: 18 additions & 9 deletions src/interface_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ mod tests {

#[tokio::test]
async fn test_two_interfaces_in_one_block() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<pre><code class=idl>
Expand All @@ -199,6 +199,7 @@ INSERT INTERFACES HERE
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply()?;
Expand All @@ -216,7 +217,7 @@ interface <dfn interface="">HTMLBlinkElement</dfn> { ... }

#[tokio::test]
async fn test_two_interfaces_in_separate_blocks() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<pre><code class=idl>
Expand All @@ -231,6 +232,7 @@ INSERT INTERFACES HERE
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply()?;
Expand All @@ -250,7 +252,7 @@ interface <dfn interface="">HTMLBlinkElement</dfn> { ... }

#[tokio::test]
async fn interface_with_partial() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<pre><code class=idl>
Expand All @@ -265,6 +267,7 @@ INSERT INTERFACES HERE
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply()?;
Expand All @@ -284,7 +287,7 @@ partial interface <span id="HTMLMarqueeElement-partial">HTMLMarqueeElement</span

#[tokio::test]
async fn interface_with_two_partials() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<pre><code class=idl>
Expand All @@ -298,6 +301,7 @@ INSERT INTERFACES HERE
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply()?;
Expand All @@ -316,7 +320,7 @@ partial interface <span id="HTMLMarqueeElement-partial-2">HTMLMarqueeElement</sp

#[tokio::test]
async fn only_partials() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<pre><code class=idl>
Expand All @@ -329,6 +333,7 @@ INSERT INTERFACES HERE
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply()?;
Expand All @@ -346,7 +351,7 @@ partial interface <span id="HTMLMarqueeElement-partial-2">HTMLMarqueeElement</sp

#[tokio::test]
async fn marker_before() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
INSERT INTERFACES HERE
Expand All @@ -358,6 +363,7 @@ interface <dfn interface>HTMLMarqueeElement</dfn> { ... }
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
proc.apply()?;
Expand All @@ -376,7 +382,8 @@ interface <dfn interface="">HTMLMarqueeElement</dfn> { ... }

#[tokio::test]
async fn no_marker() -> io::Result<()> {
let document = parse_document_async("<!DOCTYPE html>".as_bytes()).await?;
let parsed = parse_document_async("<!DOCTYPE html>".as_bytes()).await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
let result = proc.apply();
Expand All @@ -386,11 +393,12 @@ interface <dfn interface="">HTMLMarqueeElement</dfn> { ... }

#[tokio::test]
async fn duplicate_marker() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
"<!DOCTYPE html><div>INSERT INTERFACES HERE</div><div>INSERT INTERFACES HERE</div>"
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
let result = proc.apply();
Expand All @@ -400,7 +408,7 @@ interface <dfn interface="">HTMLMarqueeElement</dfn> { ... }

#[tokio::test]
async fn duplicate_dfn() -> io::Result<()> {
let document = parse_document_async(
let parsed = parse_document_async(
r#"
<!DOCTYPE html>
<pre><code class=idl>
Expand All @@ -411,6 +419,7 @@ interface <dfn interface>HTMLMarqueeElement</dfn> { ... }
.as_bytes(),
)
.await?;
let document = parsed.document().clone();
let mut proc = Processor::new();
dom_utils::scan_dom(&document, &mut |h| proc.visit(h));
let result = proc.apply();
Expand Down
7 changes: 6 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod rcdom_with_line_numbers;
mod represents;
mod self_link;
mod tag_omission;
mod variables;

#[tokio::main]
async fn main() -> io::Result<()> {
Expand All @@ -40,19 +41,22 @@ async fn run() -> io::Result<()> {
// Because parsing can jump around the tree a little, it's most reasonable
// to just parse the whole document before doing any processing. Even for
// the HTML standard, this doesn't take too long.
let document = parser::parse_document_async(tokio::io::stdin()).await?;
let parsed = parser::parse_document_async(tokio::io::stdin()).await?;
let document = parsed.document().clone();

let mut boilerplate = boilerplate::Processor::new(cache_dir.clone(), source_dir.join("demos"));
let mut represents = represents::Processor::new();
let mut annotate_attributes = annotate_attributes::Processor::new();
let mut tag_omission = tag_omission::Processor::new();
let mut interface_index = interface_index::Processor::new();
let mut self_link = self_link::Processor::new();
let mut variables = variables::Processor::new(&parsed);

// We do exactly one pass to identify the changes that need to be made.
dom_utils::scan_dom(&document, &mut |h| {
boilerplate.visit(h);
represents.visit(h);
variables.visit(h);
annotate_attributes.visit(h);
tag_omission.visit(h);
interface_index.visit(h);
Expand All @@ -64,6 +68,7 @@ async fn run() -> io::Result<()> {
// conflicts between them.
boilerplate.apply().await?;
represents.apply()?;
variables.apply()?;
annotate_attributes.apply().await?;
tag_omission.apply()?;
interface_index.apply()?;
Expand Down
13 changes: 8 additions & 5 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ pub async fn parse_fragment_async<R: AsyncRead + Unpin>(
Ok(new_children)
}

pub async fn parse_document_async<R: AsyncRead + Unpin>(r: R) -> io::Result<Handle> {
pub async fn parse_document_async<R: AsyncRead + Unpin>(r: R) -> io::Result<RcDomWithLineNumbers> {
let parser = driver::parse_document(RcDomWithLineNumbers::default(), create_error_opts());
let dom = parse_internal_async(parser, r).await?;
dom.create_error_from_parse_errors()?;

Ok(dom.document().clone())
Ok(dom)
}

fn create_error_opts() -> ParseOpts {
Expand Down Expand Up @@ -120,7 +120,8 @@ pub(crate) mod tests {
// we're in. This is important because of the special rules
// surrounding, e.g., tables. If you change this to use the body as context,
// no element at all is emitted.
let document = parse_document_async("<!DOCTYPE html><table></table>".as_bytes()).await?;
let parsed = parse_document_async("<!DOCTYPE html><table></table>".as_bytes()).await?;
let document = parsed.document().clone();
let body = document.children.borrow()[1].children.borrow()[1].clone();
assert!(body.is_html_element(&local_name!("body")));
let table = body.children.borrow()[0].clone();
Expand Down Expand Up @@ -176,7 +177,8 @@ pub(crate) mod tests {

#[tokio::test]
async fn test_fragment_error_line_number() -> io::Result<()> {
let document = parse_document_async("<!DOCTYPE html>".as_bytes()).await?;
let parsed = parse_document_async("<!DOCTYPE html>".as_bytes()).await?;
let document = parsed.document().clone();
let body = document.children.borrow()[1].children.borrow()[1].clone();
assert!(body.is_html_element(&local_name!("body")));
let result = parse_fragment_async(
Expand All @@ -194,7 +196,8 @@ pub(crate) mod tests {

#[tokio::test]
async fn test_fragment_error_exact() -> io::Result<()> {
let document = parse_document_async("<!DOCTYPE html>".as_bytes()).await?;
let parsed = parse_document_async("<!DOCTYPE html>".as_bytes()).await?;
let document = parsed.document().clone();
let body = document.children.borrow()[1].children.borrow()[1].clone();
assert!(body.is_html_element(&local_name!("body")));
let result = parse_fragment_async("&asdf;".as_bytes(), &body).await;
Expand Down
Loading
Loading