1- import { xml , XmlElement } from "../../editable" ;
21import { Point } from "../types" ;
32import { expandHandle , forPoints } from "../util" ;
43
@@ -41,16 +40,16 @@ export const renderEditable = (points: Point[], options: RenderOptions): XmlElem
4140 const stroke = options . stroke || ( options . guides ? "black" : "none" ) ;
4241 const strokeWidth = options . strokeWidth || ( options . guides ? 1 : 0 ) ;
4342
44- const xmlRoot = xml ( "svg" ) ;
43+ const xmlRoot = new XmlElement ( "svg" ) ;
4544 xmlRoot . attributes . width = options . width ;
4645 xmlRoot . attributes . height = options . height ;
4746 xmlRoot . attributes . viewBox = `0 0 ${ options . width } ${ options . height } ` ;
4847 xmlRoot . attributes . xmlns = "http://www.w3.org/2000/svg" ;
4948
50- const xmlContentGroup = xml ( "g" ) ;
49+ const xmlContentGroup = new XmlElement ( "g" ) ;
5150 xmlContentGroup . attributes . transform = options . transform || "" ;
5251
53- const xmlBlobPath = xml ( "path" ) ;
52+ const xmlBlobPath = new XmlElement ( "path" ) ;
5453 xmlBlobPath . attributes . stroke = stroke ;
5554 xmlBlobPath . attributes [ "stroke-width" ] = strokeWidth ;
5655 xmlBlobPath . attributes . fill = options . fill || "none" ;
@@ -66,7 +65,7 @@ export const renderEditable = (points: Point[], options: RenderOptions): XmlElem
6665
6766 // Bounding box.
6867 if ( options . boundingBox ) {
69- const xmlBoundingRect = xml ( "rect" ) ;
68+ const xmlBoundingRect = new XmlElement ( "rect" ) ;
7069 xmlBoundingRect . attributes . x = 0 ;
7170 xmlBoundingRect . attributes . y = 0 ;
7271 xmlBoundingRect . attributes . width = options . width ;
@@ -84,15 +83,15 @@ export const renderEditable = (points: Point[], options: RenderOptions): XmlElem
8483 const currControl = expandHandle ( curr , curr . handleOut ) ;
8584 const nextControl = expandHandle ( next , next . handleIn ) ;
8685
87- const xmlOutgoingHandleLine = xml ( "line" ) ;
86+ const xmlOutgoingHandleLine = new XmlElement ( "line" ) ;
8887 xmlOutgoingHandleLine . attributes . x1 = curr . x ;
8988 xmlOutgoingHandleLine . attributes . y1 = curr . y ;
9089 xmlOutgoingHandleLine . attributes . x2 = currControl . x ;
9190 xmlOutgoingHandleLine . attributes . y2 = currControl . y ;
9291 xmlOutgoingHandleLine . attributes [ "stroke-width" ] = size ;
9392 xmlOutgoingHandleLine . attributes . stroke = color ;
9493
95- const xmlIncomingHandleLine = xml ( "line" ) ;
94+ const xmlIncomingHandleLine = new XmlElement ( "line" ) ;
9695 xmlIncomingHandleLine . attributes . x1 = next . x ;
9796 xmlIncomingHandleLine . attributes . y1 = next . y ;
9897 xmlIncomingHandleLine . attributes . x2 = nextControl . x ;
@@ -101,19 +100,19 @@ export const renderEditable = (points: Point[], options: RenderOptions): XmlElem
101100 xmlIncomingHandleLine . attributes . stroke = color ;
102101 xmlIncomingHandleLine . attributes [ "stroke-dasharray" ] = 2 * size ;
103102
104- const xmlOutgoingHandleCircle = xml ( "circle" ) ;
103+ const xmlOutgoingHandleCircle = new XmlElement ( "circle" ) ;
105104 xmlOutgoingHandleCircle . attributes . cx = currControl . x ;
106105 xmlOutgoingHandleCircle . attributes . cy = currControl . y ;
107106 xmlOutgoingHandleCircle . attributes . r = size ;
108107 xmlOutgoingHandleCircle . attributes . fill = color ;
109108
110- const xmlIncomingHandleCircle = xml ( "circle" ) ;
109+ const xmlIncomingHandleCircle = new XmlElement ( "circle" ) ;
111110 xmlIncomingHandleCircle . attributes . cx = nextControl . x ;
112111 xmlIncomingHandleCircle . attributes . cy = nextControl . y ;
113112 xmlIncomingHandleCircle . attributes . r = size ;
114113 xmlIncomingHandleCircle . attributes . fill = color ;
115114
116- const xmlPointCircle = xml ( "circle" ) ;
115+ const xmlPointCircle = new XmlElement ( "circle" ) ;
117116 xmlPointCircle . attributes . cx = curr . x ;
118117 xmlPointCircle . attributes . cy = curr . y ;
119118 xmlPointCircle . attributes . r = 2 * size ;
@@ -129,3 +128,38 @@ export const renderEditable = (points: Point[], options: RenderOptions): XmlElem
129128
130129 return xmlRoot ;
131130} ;
131+
132+ // Structured element with tag, attributes and children.
133+ export class XmlElement {
134+ public attributes : Record < string , string | number > = { } ;
135+ public children : any [ ] = [ ] ;
136+
137+ public constructor ( public tag : string ) { }
138+
139+ public render ( ) : string {
140+ const attributes = this . renderAttributes ( ) ;
141+ const content = this . renderChildren ( ) ;
142+ if ( content === "" ) {
143+ return `<${ this . tag } ${ attributes } />` ;
144+ }
145+ return `<${ this . tag } ${ attributes } >${ content } </${ this . tag } >` ;
146+ }
147+
148+ private renderAttributes ( ) : string {
149+ const attributes = Object . keys ( this . attributes ) ;
150+ if ( attributes . length === 0 ) return "" ;
151+ let out = "" ;
152+ for ( const attribute of attributes ) {
153+ out += ` ${ attribute } ="${ this . attributes [ attribute ] } "` ;
154+ }
155+ return out ;
156+ }
157+
158+ private renderChildren ( ) : string {
159+ let out = "" ;
160+ for ( const child of this . children ) {
161+ out += child . render ( ) ;
162+ }
163+ return out ;
164+ }
165+ }
0 commit comments