11//! Augments the content attribute list for each element with a description found in the Attributes table.
22
3- use std:: collections:: HashMap ;
3+ use std:: collections:: { HashMap , HashSet } ;
44use std:: io;
55use std:: rc:: Rc ;
66
@@ -116,6 +116,11 @@ impl Processor {
116116 _ => continue ,
117117 } ;
118118
119+ // If a single row describes the same element multiple times, we don't need to repeat it.
120+ // StrTendril doesn't have logical interior mutability, so this Clippy warning is overzealous.
121+ #[ allow( clippy:: mutable_key_type) ]
122+ let mut seen_this_row: HashSet < StrTendril > = HashSet :: new ( ) ;
123+
119124 // These will be strings like "attr-input-maxlength", which identify particular element-attribute pairs.
120125 let data_x = QualName :: new ( None , ns ! ( ) , LocalName :: from ( "data-x" ) ) ;
121126 for attr_key in keys_td
@@ -124,6 +129,14 @@ impl Processor {
124129 . iter ( )
125130 . filter_map ( |c| c. get_attribute ( & data_x) . filter ( |v| !v. is_empty ( ) ) )
126131 {
132+ // If this row describes the the same attribute, with the same
133+ // identifier, for multiple elements (like attr-fae-form and
134+ // attr-dim-width), these aren't actually distinct descriptions
135+ // and we need not join them.
136+ if !seen_this_row. insert ( attr_key. clone ( ) ) {
137+ continue ;
138+ }
139+
127140 // Find the <!-- or: --> comment, if one exists, and extract its contents.
128141 let description = description_td. children . borrow ( ) ;
129142 let mut variant_comment = None ;
@@ -463,6 +476,54 @@ mod tests {
463476<table id="attributes-1"><tbody>
464477 <tr><th><code data-x="">name</code></th><td><code data-x="attr-a-name">a</code></td><td>Anchor name
465478 </td></tr><tr><th><code data-x="">name</code></th><td><code data-x="attr-a-name">a</code></td><td>Name of the anchor
479+ </td></tr></tbody></table></body></html>
480+ "# . trim( )
481+ ) ;
482+ Ok ( ( ) )
483+ }
484+
485+ #[ tokio:: test]
486+ async fn test_identical_links ( ) -> io:: Result < ( ) > {
487+ // This checks the same identifier can be linked multiple times without
488+ // repeating the description.
489+ let document = parse_document_async (
490+ r#"
491+ <h3>The img element</h3>
492+ <dl class="element">
493+ <dt><span data-x="concept-element-attributes">Content attributes</span>
494+ <dd><code data-x="attr-dim-width">width</code>
495+ </dl>
496+ <h3>The video element</h3>
497+ <dl class="element">
498+ <dt><span data-x="concept-element-attributes">Content attributes</span>
499+ <dd><code data-x="attr-dim-width">width</code>
500+ </dl>
501+ <h3>Attributes</h3>
502+ <table id="attributes-1"><tbody>
503+ <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
504+ </tbody></table>
505+ "# . trim ( ) . as_bytes ( ) ) . await ?;
506+ let mut proc = Processor :: new ( ) ;
507+ dom_utils:: scan_dom ( & document, & mut |h| proc. visit ( h) ) ;
508+ proc. apply ( ) . await ?;
509+ assert_eq ! (
510+ serialize_for_test( & [ document] ) ,
511+ r#"
512+ <html><head></head><body><h3>The img element</h3>
513+ <dl class="element">
514+ <dt><span data-x="concept-element-attributes">Content attributes</span>
515+ </dt><dd><code data-x="attr-dim-width">width</code>
516+ — Horizontal dimension
517+ </dd></dl>
518+ <h3>The video element</h3>
519+ <dl class="element">
520+ <dt><span data-x="concept-element-attributes">Content attributes</span>
521+ </dt><dd><code data-x="attr-dim-width">width</code>
522+ — Horizontal dimension
523+ </dd></dl>
524+ <h3>Attributes</h3>
525+ <table id="attributes-1"><tbody>
526+ <tr><th><code data-x="">width</code></th><td><code data-x="attr-dim-width">img</code>; <code data-x="attr-dim-width">video</code></td><td>Horizontal dimension
466527</td></tr></tbody></table></body></html>
467528 "# . trim( )
468529 ) ;
0 commit comments