66
77use std:: path:: { Path , PathBuf } ;
88
9- use html5ever:: { interface:: QualName , namespace_url, ns, tendril:: TendrilSink , LocalName } ;
9+ use html5ever:: {
10+ interface:: QualName ,
11+ namespace_url, ns,
12+ serialize:: { HtmlSerializer , SerializeOpts , Serializer , TraversalScope } ,
13+ tendril:: TendrilSink ,
14+ LocalName ,
15+ } ;
1016pub use kuchiki:: NodeRef ;
11- use kuchiki:: { Attribute , ExpandedName } ;
17+ use kuchiki:: { Attribute , ExpandedName , NodeData } ;
1218use serde:: Serialize ;
1319#[ cfg( feature = "isolation" ) ]
1420use serialize_to_javascript:: DefaultTemplate ;
@@ -24,6 +30,90 @@ pub const SCRIPT_NONCE_TOKEN: &str = "__TAURI_SCRIPT_NONCE__";
2430/// The token used for style nonces.
2531pub const STYLE_NONCE_TOKEN : & str = "__TAURI_STYLE_NONCE__" ;
2632
33+ // taken from https://github.com/kuchiki-rs/kuchiki/blob/57ee6920d835315a498e748ba4b07a851ae5e498/src/serializer.rs#L12
34+ fn serialize_node_ref_internal < S : Serializer > (
35+ node : & NodeRef ,
36+ serializer : & mut S ,
37+ traversal_scope : TraversalScope ,
38+ ) -> crate :: Result < ( ) > {
39+ match ( traversal_scope, node. data ( ) ) {
40+ ( ref scope, & NodeData :: Element ( ref element) ) => {
41+ if * scope == TraversalScope :: IncludeNode {
42+ let attrs = element. attributes . borrow ( ) ;
43+
44+ // Unfortunately we need to allocate something to hold these &'a QualName
45+ let attrs = attrs
46+ . map
47+ . iter ( )
48+ . map ( |( name, attr) | {
49+ (
50+ QualName :: new ( attr. prefix . clone ( ) , name. ns . clone ( ) , name. local . clone ( ) ) ,
51+ & attr. value ,
52+ )
53+ } )
54+ . collect :: < Vec < _ > > ( ) ;
55+
56+ serializer. start_elem (
57+ element. name . clone ( ) ,
58+ attrs. iter ( ) . map ( |& ( ref name, value) | ( name, & * * value) ) ,
59+ ) ?
60+ }
61+
62+ let children = match element. template_contents . as_ref ( ) {
63+ Some ( template_root) => template_root. children ( ) ,
64+ None => node. children ( ) ,
65+ } ;
66+ for child in children {
67+ serialize_node_ref_internal ( & child, serializer, TraversalScope :: IncludeNode ) ?
68+ }
69+
70+ if * scope == TraversalScope :: IncludeNode {
71+ serializer. end_elem ( element. name . clone ( ) ) ?
72+ }
73+ Ok ( ( ) )
74+ }
75+
76+ ( _, & NodeData :: DocumentFragment ) | ( _, & NodeData :: Document ( _) ) => {
77+ for child in node. children ( ) {
78+ serialize_node_ref_internal ( & child, serializer, TraversalScope :: IncludeNode ) ?
79+ }
80+ Ok ( ( ) )
81+ }
82+
83+ ( TraversalScope :: ChildrenOnly ( _) , _) => Ok ( ( ) ) ,
84+
85+ ( TraversalScope :: IncludeNode , & NodeData :: Doctype ( ref doctype) ) => {
86+ serializer. write_doctype ( & doctype. name ) . map_err ( Into :: into)
87+ }
88+ ( TraversalScope :: IncludeNode , & NodeData :: Text ( ref text) ) => {
89+ serializer. write_text ( & text. borrow ( ) ) . map_err ( Into :: into)
90+ }
91+ ( TraversalScope :: IncludeNode , & NodeData :: Comment ( ref text) ) => {
92+ serializer. write_comment ( & text. borrow ( ) ) . map_err ( Into :: into)
93+ }
94+ ( TraversalScope :: IncludeNode , & NodeData :: ProcessingInstruction ( ref contents) ) => {
95+ let contents = contents. borrow ( ) ;
96+ serializer
97+ . write_processing_instruction ( & contents. 0 , & contents. 1 )
98+ . map_err ( Into :: into)
99+ }
100+ }
101+ }
102+
103+ /// Serializes the node to HTML.
104+ pub fn serialize_node ( node : & NodeRef ) -> Vec < u8 > {
105+ let mut u8_vec = Vec :: new ( ) ;
106+ let mut ser = HtmlSerializer :: new (
107+ & mut u8_vec,
108+ SerializeOpts {
109+ traversal_scope : TraversalScope :: IncludeNode ,
110+ ..Default :: default ( )
111+ } ,
112+ ) ;
113+ serialize_node_ref_internal ( node, & mut ser, TraversalScope :: IncludeNode ) . unwrap ( ) ;
114+ u8_vec
115+ }
116+
27117/// Parses the given HTML string.
28118pub fn parse ( html : String ) -> NodeRef {
29119 kuchiki:: parse_html ( ) . one ( html)
0 commit comments