22 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44
5+ use std:: cell:: RefCell ;
6+
7+ use base64:: Engine as _;
58use dom_struct:: dom_struct;
6- use html5ever:: { LocalName , Prefix , local_name , ns } ;
9+ use html5ever:: { LocalName , Prefix } ;
710use js:: rust:: HandleObject ;
8- use layout_api:: SVGSVGData ;
9- use style:: attr:: AttrValue ;
11+ use layout_api:: SVGElementData ;
12+ use servo_url:: ServoUrl ;
13+ use xml5ever:: serialize:: TraversalScope ;
1014
1115use crate :: dom:: attr:: Attr ;
1216use crate :: dom:: bindings:: inheritance:: Castable ;
1317use crate :: dom:: bindings:: root:: { DomRoot , LayoutDom } ;
14- use crate :: dom:: bindings:: str:: DOMString ;
1518use crate :: dom:: document:: Document ;
16- use crate :: dom:: element:: { AttributeMutation , Element , LayoutElementHelpers } ;
19+ use crate :: dom:: element:: AttributeMutation ;
1720use crate :: dom:: node:: Node ;
1821use crate :: dom:: svggraphicselement:: SVGGraphicsElement ;
1922use crate :: dom:: virtualmethods:: VirtualMethods ;
2023use crate :: script_runtime:: CanGc ;
2124
22- const DEFAULT_WIDTH : u32 = 300 ;
23- const DEFAULT_HEIGHT : u32 = 150 ;
24-
2525#[ dom_struct]
2626pub ( crate ) struct SVGSVGElement {
2727 svggraphicselement : SVGGraphicsElement ,
28+ #[ no_trace]
29+ cached_serialized_data : RefCell < Option < ServoUrl > > ,
2830}
2931
3032impl SVGSVGElement {
@@ -35,6 +37,7 @@ impl SVGSVGElement {
3537 ) -> SVGSVGElement {
3638 SVGSVGElement {
3739 svggraphicselement : SVGGraphicsElement :: new_inherited ( local_name, prefix, document) ,
40+ cached_serialized_data : Default :: default ( ) ,
3841 }
3942 }
4043
@@ -53,23 +56,28 @@ impl SVGSVGElement {
5356 can_gc,
5457 )
5558 }
59+
60+ pub ( crate ) fn cache_serialized_data ( & self ) {
61+ let source: String = self
62+ . upcast :: < Node > ( )
63+ . xml_serialize ( TraversalScope :: IncludeNode )
64+ . into ( ) ;
65+ let base64 = base64:: engine:: general_purpose:: STANDARD . encode ( source) ;
66+ let source = format ! ( "data:image/svg+xml;base64,{}" , base64) ;
67+ if let Ok ( url) = ServoUrl :: parse ( & source) {
68+ * self . cached_serialized_data . borrow_mut ( ) = Some ( url) ;
69+ }
70+ }
5671}
5772
5873pub ( crate ) trait LayoutSVGSVGElementHelpers {
59- fn data ( self ) -> SVGSVGData ;
74+ fn data ( self ) -> SVGElementData ;
6075}
6176
6277impl LayoutSVGSVGElementHelpers for LayoutDom < ' _ , SVGSVGElement > {
63- fn data ( self ) -> SVGSVGData {
64- let width_attr = self
65- . upcast :: < Element > ( )
66- . get_attr_for_layout ( & ns ! ( ) , & local_name ! ( "width" ) ) ;
67- let height_attr = self
68- . upcast :: < Element > ( )
69- . get_attr_for_layout ( & ns ! ( ) , & local_name ! ( "height" ) ) ;
70- SVGSVGData {
71- width : width_attr. map_or ( DEFAULT_WIDTH , |val| val. as_uint ( ) ) ,
72- height : height_attr. map_or ( DEFAULT_HEIGHT , |val| val. as_uint ( ) ) ,
78+ fn data ( self ) -> SVGElementData {
79+ SVGElementData {
80+ source : self . unsafe_get ( ) . cached_serialized_data . borrow ( ) . clone ( ) ,
7381 }
7482 }
7583}
@@ -83,16 +91,14 @@ impl VirtualMethods for SVGSVGElement {
8391 self . super_type ( )
8492 . unwrap ( )
8593 . attribute_mutated ( attr, mutation, can_gc) ;
94+ * self . cached_serialized_data . borrow_mut ( ) = None ;
8695 }
8796
88- fn parse_plain_attribute ( & self , name : & LocalName , value : DOMString ) -> AttrValue {
89- match * name {
90- local_name ! ( "width" ) => AttrValue :: from_u32 ( value. into ( ) , DEFAULT_WIDTH ) ,
91- local_name ! ( "height" ) => AttrValue :: from_u32 ( value. into ( ) , DEFAULT_HEIGHT ) ,
92- _ => self
93- . super_type ( )
94- . unwrap ( )
95- . parse_plain_attribute ( name, value) ,
97+ fn children_changed ( & self , mutation : & super :: node:: ChildrenMutation ) {
98+ if let Some ( super_type) = self . super_type ( ) {
99+ super_type. children_changed ( mutation) ;
96100 }
101+
102+ * self . cached_serialized_data . borrow_mut ( ) = None ;
97103 }
98104}
0 commit comments