Skip to content

Commit 2722c7a

Browse files
committed
feat(Editor): make Editor generic
Turns the previous `Editor` class which used to extend LitElement into an `EditV2Editor` class which implements a generic `Editor` interface and is not related to rendering at all.
1 parent 650a019 commit 2722c7a

File tree

8 files changed

+145
-403
lines changed

8 files changed

+145
-403
lines changed

Editor.spec.ts

Lines changed: 47 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
/* eslint-disable @typescript-eslint/no-unused-expressions */
2-
import { html } from "lit";
3-
4-
import { expect, fixture } from "@open-wc/testing";
2+
import { expect } from "@open-wc/testing";
53

64
import { assert, property } from "fast-check";
75

@@ -18,28 +16,24 @@ import {
1816
xmlAttributeName,
1917
} from "./testHelpers.js";
2018

21-
import { newEditEventV2 } from "./edit-event.js";
22-
2319
import { EditV2, isSetAttributes, isSetTextContent } from "./editv2.js";
2420

25-
import { Editor } from "./Editor.js";
26-
27-
customElements.define("editor-element", Editor);
21+
import { Editor, EditV2Editor } from "./Editor.js";
2822

2923
describe("Utility function to handle EditV2 edits", () => {
30-
let editor: Editor;
24+
let editor: Editor<EditV2>;
3125
let sclDoc: XMLDocument;
3226

3327
beforeEach(async () => {
34-
editor = await fixture<Editor>(html`<editor-element></editor-element>`);
28+
editor = new EditV2Editor();
3529
sclDoc = new DOMParser().parseFromString(sclDocString, "application/xml");
3630
});
3731

3832
it("inserts an element on Insert", () => {
3933
const parent = sclDoc.documentElement;
4034
const node = sclDoc.createElement("test");
4135
const reference = sclDoc.querySelector("Substation");
42-
editor.dispatchEvent(newEditEventV2({ parent, node, reference }, {}));
36+
editor.edit({ parent, node, reference }, {});
4337
expect(sclDoc.documentElement.querySelector("test")).to.have.property(
4438
"nextSibling",
4539
reference,
@@ -48,39 +42,37 @@ describe("Utility function to handle EditV2 edits", () => {
4842

4943
it("removes an element on Remove", () => {
5044
const node = sclDoc.querySelector("Substation")!;
51-
editor.dispatchEvent(newEditEventV2({ node }, {}));
45+
editor.edit({ node }, {});
5246

5347
expect(sclDoc.querySelector("Substation")).to.not.exist;
5448
});
5549

5650
it("updates an element's attributes on SetAttributes", () => {
5751
const element = sclDoc.querySelector("Substation")!;
58-
editor.dispatchEvent(
59-
newEditEventV2(
60-
{
61-
element,
62-
attributes: {
63-
name: "A2",
64-
desc: null,
65-
["__proto__"]: "a string", // covers a rare edge case branch
52+
editor.edit(
53+
{
54+
element,
55+
attributes: {
56+
name: "A2",
57+
desc: null,
58+
["__proto__"]: "a string", // covers a rare edge case branch
59+
},
60+
attributesNS: {
61+
"http://example.org/myns": {
62+
"myns:attr": "value1",
63+
"myns:attr2": "value1",
6664
},
67-
attributesNS: {
68-
"http://example.org/myns": {
69-
"myns:attr": "value1",
70-
"myns:attr2": "value1",
71-
},
72-
"http://example.org/myns2": {
73-
attr: "value2",
74-
attr2: "value2",
75-
},
76-
"http://example.org/myns3": {
77-
attr: "value3",
78-
attr2: "value3",
79-
},
65+
"http://example.org/myns2": {
66+
attr: "value2",
67+
attr2: "value2",
68+
},
69+
"http://example.org/myns3": {
70+
attr: "value3",
71+
attr2: "value3",
8072
},
8173
},
82-
{},
83-
),
74+
},
75+
{},
8476
);
8577

8678
expect(element.getAttribute("name")).to.equal("A2");
@@ -98,12 +90,10 @@ describe("Utility function to handle EditV2 edits", () => {
9890
const element = sclDoc.querySelector("SCL")!;
9991

10092
const newTextContent = "someNewTextContent";
101-
editor.dispatchEvent(
102-
newEditEventV2({
103-
element,
104-
textContent: newTextContent,
105-
}),
106-
);
93+
editor.edit({
94+
element,
95+
textContent: newTextContent,
96+
});
10797

10898
expect(element.textContent).to.equal(newTextContent);
10999
});
@@ -139,8 +129,8 @@ describe("Utility function to handle EditV2 edits", () => {
139129
textContent: "someNewTextContent",
140130
};
141131

142-
editor.dispatchEvent(newEditEventV2(edit1, {}));
143-
editor.dispatchEvent(newEditEventV2(edit2, { squash: true }));
132+
editor.edit(edit1, {});
133+
editor.edit(edit2, { squash: true });
144134

145135
const history = editor.history;
146136
expect(history).to.have.length(1);
@@ -157,14 +147,12 @@ describe("Utility function to handle EditV2 edits", () => {
157147
const reference = sclDoc.querySelector("Substation");
158148
const node1 = sclDoc.createElement("test1");
159149
const node2 = sclDoc.createElement("test2");
160-
editor.dispatchEvent(
161-
newEditEventV2(
162-
[
163-
{ parent, node: node1, reference },
164-
{ parent, node: node2, reference },
165-
],
166-
{},
167-
),
150+
editor.edit(
151+
[
152+
{ parent, node: node1, reference },
153+
{ parent, node: node2, reference },
154+
],
155+
{},
168156
);
169157
expect(sclDoc.documentElement.querySelector("test1")).to.have.property(
170158
"nextSibling",
@@ -181,7 +169,7 @@ describe("Utility function to handle EditV2 edits", () => {
181169
it("undoes a committed edit on undo() call", () => {
182170
const node = sclDoc.querySelector("Substation")!;
183171

184-
editor.dispatchEvent(newEditEventV2({ node }));
172+
editor.edit({ node });
185173
editor.undo();
186174

187175
expect(sclDoc.querySelector("Substation")).to.exist;
@@ -191,7 +179,7 @@ describe("Utility function to handle EditV2 edits", () => {
191179
it("redoes an undone edit on redo() call", () => {
192180
const node = sclDoc.querySelector("Substation")!;
193181

194-
editor.dispatchEvent(newEditEventV2({ node }));
182+
editor.edit({ node });
195183
editor.undo();
196184
editor.redo();
197185

@@ -208,7 +196,7 @@ describe("Utility function to handle EditV2 edits", () => {
208196
return insert(nodes);
209197
}),
210198
(edit) => {
211-
editor.dispatchEvent(newEditEventV2(edit));
199+
editor.edit(edit);
212200
if (isValidInsert(edit))
213201
return (
214202
edit.node.parentElement === edit.parent &&
@@ -227,7 +215,7 @@ describe("Utility function to handle EditV2 edits", () => {
227215
return setTextContent(nodes);
228216
}),
229217
(edit) => {
230-
editor.dispatchEvent(newEditEventV2(edit));
218+
editor.edit(edit);
231219

232220
return edit.element.textContent === edit.textContent;
233221
},
@@ -239,7 +227,7 @@ describe("Utility function to handle EditV2 edits", () => {
239227
property(
240228
testDocs.chain(([{ nodes }]) => setAttributes(nodes)),
241229
(edit) => {
242-
editor.dispatchEvent(newEditEventV2(edit));
230+
editor.edit(edit);
243231
return (
244232
Object.entries(edit.attributes)
245233
.filter(([name]) => xmlAttributeName.test(name))
@@ -275,7 +263,7 @@ describe("Utility function to handle EditV2 edits", () => {
275263
property(
276264
testDocs.chain(([{ nodes }]) => remove(nodes)),
277265
({ node }) => {
278-
editor.dispatchEvent(newEditEventV2({ node }));
266+
editor.edit({ node });
279267
return !node.parentNode;
280268
},
281269
),
@@ -290,7 +278,7 @@ describe("Utility function to handle EditV2 edits", () => {
290278
doc.cloneNode(true),
291279
);
292280
edits.forEach((a: EditV2) => {
293-
editor.dispatchEvent(newEditEventV2(a, { squash }));
281+
editor.edit(a, { squash });
294282
});
295283
if (editor.editCount) editor.undo(editor.editCount);
296284
expect(doc1).to.satisfy((doc: XMLDocument) =>
@@ -310,7 +298,7 @@ describe("Utility function to handle EditV2 edits", () => {
310298
testDocs.chain((docs) => undoRedoTestCases(...docs)),
311299
({ doc1, doc2, edits }: UndoRedoTestCase) => {
312300
edits.forEach((a: EditV2) => {
313-
editor.dispatchEvent(newEditEventV2(a));
301+
editor.edit(a);
314302
});
315303
const [oldDoc1, oldDoc2] = [doc1, doc2].map((doc) =>
316304
new XMLSerializer().serializeToString(doc),

0 commit comments

Comments
 (0)