@@ -7,14 +7,17 @@ use html5ever::{
77 tendril:: StrTendril ,
88 tree_builder:: { ElementFlags , NodeOrText , QuirksMode } ,
99} ;
10- use markup5ever_rcdom:: { Handle , RcDom } ;
10+ use markup5ever_rcdom:: { Handle , Node , RcDom } ;
1111use std:: borrow:: Cow ;
12- use std:: cell:: Cell ;
12+ use std:: cell:: { Cell , RefCell } ;
13+ use std:: collections:: HashMap ;
1314use std:: io;
15+ use std:: rc:: Rc ;
1416
1517pub struct RcDomWithLineNumbers {
1618 dom : RcDom ,
1719 current_line : Cell < u64 > ,
20+ node_line_map : RefCell < HashMap < * const Node , u64 > > ,
1821}
1922
2023#[ cfg( test) ]
@@ -48,13 +51,21 @@ impl RcDomWithLineNumbers {
4851 Ok ( ( ) )
4952 }
5053 }
54+
55+ /// Returns the 1-based line number where the element represented by `handle`
56+ /// was created, if known.
57+ pub fn line_number_for ( & self , handle : & Handle ) -> Option < u64 > {
58+ let key = Rc :: as_ptr ( handle) ;
59+ self . node_line_map . borrow ( ) . get ( & key) . cloned ( )
60+ }
5161}
5262
5363impl Default for RcDomWithLineNumbers {
5464 fn default ( ) -> Self {
5565 Self {
5666 dom : RcDom :: default ( ) ,
5767 current_line : Cell :: new ( 1 ) ,
68+ node_line_map : RefCell :: new ( HashMap :: new ( ) ) ,
5869 }
5970 }
6071}
@@ -81,20 +92,27 @@ impl TreeSink for RcDomWithLineNumbers {
8192 self
8293 }
8394
95+ // Override to record the current line number for each created element handle.
96+ fn create_element (
97+ & self ,
98+ name : QualName ,
99+ attrs : Vec < Attribute > ,
100+ flags : ElementFlags ,
101+ ) -> Self :: Handle {
102+ let h = self . dom . create_element ( name, attrs, flags) ;
103+ let key = Rc :: as_ptr ( & h) ;
104+ let line = self . current_line . get ( ) ;
105+ self . node_line_map . borrow_mut ( ) . insert ( key, line) ;
106+ h
107+ }
108+
84109 // Delegate all other methods to RcDom.
85110 delegate ! {
86111 to self . dom {
87112 fn get_document( & self ) -> Self :: Handle ;
88113
89114 fn elem_name<' a>( & ' a self , target: & ' a Self :: Handle ) -> ExpandedName <' a>;
90115
91- fn create_element(
92- & self ,
93- name: QualName ,
94- attrs: Vec <Attribute >,
95- flags: ElementFlags ,
96- ) -> Self :: Handle ;
97-
98116 fn create_comment( & self , text: StrTendril ) -> Self :: Handle ;
99117
100118 fn create_pi( & self , target: StrTendril , data: StrTendril ) -> Self :: Handle ;
0 commit comments