Skip to content

Commit 644a318

Browse files
committed
simplify xml generator constructor's signature
1 parent 078a86d commit 644a318

File tree

3 files changed

+80
-83
lines changed

3 files changed

+80
-83
lines changed

internal/svg/render.ts

Lines changed: 65 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {loopAccess} from "./util";
22
import {Point, interpolate} from "./point";
3-
import {Xml} from "../xml";
3+
import {xml} from "../xml";
44

55
export interface RenderOptions {
66
// Viewport size.
@@ -69,27 +69,23 @@ export const render = (p: Point[], opt: RenderOptions): string => {
6969
const stroke = opt.stroke || (opt.guides ? "black" : "none");
7070
const strokeWidth = opt.strokeWidth || (opt.guides ? 1 : 0);
7171

72-
const xmlRoot = new Xml("svg", {
73-
width: opt.width,
74-
height: opt.height,
75-
viewBox: `0 0 ${opt.width} ${opt.height}`,
76-
xmlns: "http://www.w3.org/2000/svg",
77-
});
72+
const xmlRoot = xml("svg");
73+
xmlRoot.attributes.width = opt.width;
74+
xmlRoot.attributes.height = opt.height;
75+
xmlRoot.attributes.viewBox = `0 0 ${opt.width} ${opt.height}`;
76+
xmlRoot.attributes.xmlns = "http://www.w3.org/2000/svg";
7877

79-
const xmlContent = new Xml("g", {
80-
transform: opt.transform || "",
81-
});
78+
const xmlContentGroup = xml("g");
79+
xmlContentGroup.attributes.transform = opt.transform || "";
8280

83-
xmlRoot.children.push(xmlContent);
81+
const xmlBlobPath = xml("path");
82+
xmlBlobPath.attributes.stroke = stroke;
83+
xmlBlobPath.attributes["stroke-width"] = strokeWidth;
84+
xmlBlobPath.attributes.fill = opt.fill || "none";
85+
xmlBlobPath.attributes.d = path;
8486

85-
xmlContent.children.push(
86-
new Xml("path", {
87-
stroke,
88-
"stroke-width": strokeWidth,
89-
fill: opt.fill || "none",
90-
d: path,
91-
}),
92-
);
87+
xmlContentGroup.children.push(xmlBlobPath);
88+
xmlRoot.children.push(xmlContentGroup);
9389

9490
// Render guides if configured to do so.
9591
if (opt.guides) {
@@ -98,18 +94,16 @@ export const render = (p: Point[], opt: RenderOptions): string => {
9894

9995
// Bounding box.
10096
if (opt.boundingBox) {
101-
xmlContent.children.push(
102-
new Xml("rect", {
103-
x: 0,
104-
y: 0,
105-
width: opt.width,
106-
height: opt.height,
107-
fill: "none",
108-
stroke: color,
109-
"stroke-width": 2 * size,
110-
"stroke-dasharray": 2 * size,
111-
}),
112-
);
97+
const xmlBoundingRect = xml("rect");
98+
xmlBoundingRect.attributes.x = 0;
99+
xmlBoundingRect.attributes.y = 0;
100+
xmlBoundingRect.attributes.width = opt.width;
101+
xmlBoundingRect.attributes.height = opt.height;
102+
xmlBoundingRect.attributes.fill = "none";
103+
xmlBoundingRect.attributes.stroke = color;
104+
xmlBoundingRect.attributes["stroke-width"] = 2 * size;
105+
xmlBoundingRect.attributes["stroke-dasharray"] = 2 * size;
106+
xmlContentGroup.children.push(xmlBoundingRect);
113107
}
114108

115109
// Points and handles.
@@ -118,43 +112,46 @@ export const render = (p: Point[], opt: RenderOptions): string => {
118112
const hands = loopAccess(handles)(i);
119113
const nextPoint = loopAccess(points)(i + 1);
120114

121-
xmlContent.children.push(
122-
new Xml("line", {
123-
x1: x,
124-
y1: y,
125-
x2: hands.x1,
126-
y2: hands.y1,
127-
"stroke-width": size,
128-
stroke: color,
129-
}),
130-
new Xml("line", {
131-
x1: nextPoint.x,
132-
y1: nextPoint.y,
133-
x2: hands.x2,
134-
y2: hands.y2,
135-
"stroke-width": size,
136-
stroke: color,
137-
"stroke-dasharray": 2 * size,
138-
}),
139-
new Xml("circle", {
140-
cx: hands.x1,
141-
cy: hands.y1,
142-
r: size,
143-
fill: color,
144-
}),
145-
new Xml("circle", {
146-
cx: hands.x2,
147-
cy: hands.y2,
148-
r: size,
149-
fill: color,
150-
}),
151-
new Xml("circle", {
152-
cx: x,
153-
cy: y,
154-
r: 2 * size,
155-
fill: color,
156-
}),
157-
);
115+
const xmlIncomingHandleLine = xml("line");
116+
xmlIncomingHandleLine.attributes.x1 = x;
117+
xmlIncomingHandleLine.attributes.y1 = y;
118+
xmlIncomingHandleLine.attributes.x2 = hands.x1;
119+
xmlIncomingHandleLine.attributes.y2 = hands.y1;
120+
xmlIncomingHandleLine.attributes["stroke-width"] = size;
121+
xmlIncomingHandleLine.attributes.stroke = color;
122+
123+
const xmlOutgoingHandleLine = xml("line");
124+
xmlOutgoingHandleLine.attributes.x1 = nextPoint.x;
125+
xmlOutgoingHandleLine.attributes.y1 = nextPoint.y;
126+
xmlOutgoingHandleLine.attributes.x2 = hands.x2;
127+
xmlOutgoingHandleLine.attributes.y2 = hands.y2;
128+
xmlOutgoingHandleLine.attributes["stroke-width"] = size;
129+
xmlOutgoingHandleLine.attributes.stroke = color;
130+
xmlOutgoingHandleLine.attributes["stroke-dasharray"] = 2 * size;
131+
132+
const xmlIncomingHandleCircle = xml("circle");
133+
xmlIncomingHandleCircle.attributes.cx = hands.x1;
134+
xmlIncomingHandleCircle.attributes.cy = hands.y1;
135+
xmlIncomingHandleCircle.attributes.r = size;
136+
xmlIncomingHandleCircle.attributes.fill = color;
137+
138+
const xmlOutgoingHandleCircle = xml("circle");
139+
xmlOutgoingHandleCircle.attributes.cx = hands.x2;
140+
xmlOutgoingHandleCircle.attributes.cy = hands.y2;
141+
xmlOutgoingHandleCircle.attributes.r = size;
142+
xmlOutgoingHandleCircle.attributes.fill = color;
143+
144+
const xmlPointCircle = xml("circle");
145+
xmlPointCircle.attributes.cx = x;
146+
xmlPointCircle.attributes.cy = y;
147+
xmlPointCircle.attributes.r = 2 * size;
148+
xmlPointCircle.attributes.fill = color;
149+
150+
xmlContentGroup.children.push(xmlIncomingHandleLine);
151+
xmlContentGroup.children.push(xmlOutgoingHandleLine);
152+
xmlContentGroup.children.push(xmlIncomingHandleCircle);
153+
xmlContentGroup.children.push(xmlOutgoingHandleCircle);
154+
xmlContentGroup.children.push(xmlPointCircle);
158155
}
159156
}
160157

internal/xml/index.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ export interface IXml {
33
render(): string;
44
}
55

6+
// Shortcut to create an XmlElement without "new";
7+
export const xml = (tag: string) => new XmlElement(tag);
8+
69
// Structured element with tag, attributes and children.
7-
export class Xml implements IXml {
8-
public tag: string;
9-
public attributes: Record<string, string | number>;
10-
public children: IXml[];
10+
export class XmlElement implements IXml {
11+
public attributes: Record<string, string | number> = {};
12+
public children: IXml[] = [];
1113

12-
public constructor(tag: string, attributes?: Xml["attributes"]) {
13-
this.tag = tag;
14-
this.attributes = attributes || {};
15-
this.children = [];
16-
}
14+
public constructor(public tag: string) {}
1715

1816
public render(): string {
1917
const attributes = this.renderAttributes();

internal/xml/test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
import {Xml} from ".";
1+
import {xml} from ".";
22

33
describe("internal/xml/xml", () => {
44
describe("render", () => {
55
it("should render element tags", () => {
6-
const elem = new Xml("test");
6+
const elem = xml("test");
77
expect(elem.render()).toBe("<test/>");
88
});
99

1010
it("should render element attributes", () => {
11-
const elem = new Xml("test", {a: 1, "b-c": "d"});
11+
const elem = xml("test");
12+
elem.attributes.a = 1;
13+
elem.attributes["b-c"] = "d";
1214
expect(elem.render()).toBe('<test a="1" b-c="d"/>');
1315
});
1416

1517
it("should render nested elements", () => {
16-
const a = new Xml("a");
17-
const aa = new Xml("aa");
18-
const ab = new Xml("ab");
18+
const a = xml("a");
19+
const aa = xml("aa");
20+
const ab = xml("ab");
1921
const aba = {render: () => "aba"};
2022
a.children.push(aa);
2123
a.children.push(ab);

0 commit comments

Comments
 (0)