Skip to content

Commit 01d58ec

Browse files
authored
Merge pull request #91 from inokawa/is-block-fn
Add isBlock option
2 parents df00bbc + 3d4cb8e commit 01d58ec

File tree

7 files changed

+299
-68
lines changed

7 files changed

+299
-68
lines changed

e2e/edix.ts

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,70 @@ export const initEdixHelpers = async (context: BrowserContext) => {
2828

2929
export const NON_EDITABLE_PLACEHOLDER = "$";
3030

31-
export const getText = async (editable: Locator): Promise<string[]> => {
32-
return editable.evaluate((element, NON_EDITABLE_PLACEHOLDER) => {
33-
const document = element.ownerDocument;
34-
return window.edix.takeDomSnapshot(document, element).map((r) => {
35-
return r.reduce<string>((acc, n) => {
36-
return acc + (typeof n === "string" ? n : NON_EDITABLE_PLACEHOLDER);
37-
}, "");
38-
});
39-
}, NON_EDITABLE_PLACEHOLDER);
31+
export const getText = async (
32+
editable: Locator,
33+
config: { blockTag?: string } = {}
34+
): Promise<string[]> => {
35+
return editable.evaluate(
36+
(element, [NON_EDITABLE_PLACEHOLDER, { blockTag }]) => {
37+
const document = element.ownerDocument;
38+
return window.edix
39+
.takeDomSnapshot(document, element, {
40+
isBlock: blockTag
41+
? (n) => n.tagName === blockTag.toUpperCase()
42+
: undefined,
43+
})
44+
.map((r) => {
45+
return r.reduce<string>((acc, n) => {
46+
return acc + (typeof n === "string" ? n : NON_EDITABLE_PLACEHOLDER);
47+
}, "");
48+
});
49+
},
50+
[NON_EDITABLE_PLACEHOLDER, config] as const
51+
);
4052
};
4153

42-
export const getSeletedText = (editable: Locator): Promise<string[]> => {
43-
return editable.evaluate((element, NON_EDITABLE_PLACEHOLDER) => {
44-
const document = element.ownerDocument;
45-
const selection = document.getSelection()!;
46-
const range = selection.getRangeAt(0)!.cloneContents();
47-
return window.edix.takeDomSnapshot(document, range).map((r) => {
48-
return r.reduce<string>((acc, n) => {
49-
return acc + (typeof n === "string" ? n : NON_EDITABLE_PLACEHOLDER);
50-
}, "");
51-
});
52-
}, NON_EDITABLE_PLACEHOLDER);
54+
export const getSeletedText = (
55+
editable: Locator,
56+
config: { blockTag?: string } = {}
57+
): Promise<string[]> => {
58+
return editable.evaluate(
59+
(element, [NON_EDITABLE_PLACEHOLDER, { blockTag }]) => {
60+
const document = element.ownerDocument;
61+
const selection = document.getSelection()!;
62+
const range = selection.getRangeAt(0)!.cloneContents();
63+
return window.edix
64+
.takeDomSnapshot(document, range, {
65+
isBlock: blockTag
66+
? (n) => n.tagName === blockTag.toUpperCase()
67+
: undefined,
68+
})
69+
.map((r) => {
70+
return r.reduce<string>((acc, n) => {
71+
return acc + (typeof n === "string" ? n : NON_EDITABLE_PLACEHOLDER);
72+
}, "");
73+
});
74+
},
75+
[NON_EDITABLE_PLACEHOLDER, config] as const
76+
);
5377
};
5478

5579
export const getSelection = (
5680
editable: Locator,
57-
isSingleline: boolean = false
81+
config: { isSingleline?: boolean; blockTag?: string } = {}
5882
): Promise<SelectionSnapshot> => {
59-
return editable.evaluate((element, isSingleline) => {
83+
return editable.evaluate((element, { isSingleline = false, blockTag }) => {
6084
return window.edix.takeSelectionSnapshot(
6185
element.ownerDocument,
6286
element,
63-
isSingleline
87+
isSingleline,
88+
{
89+
isBlock: blockTag
90+
? (n) => n.tagName === blockTag.toUpperCase()
91+
: undefined,
92+
}
6493
);
65-
}, isSingleline);
94+
}, config);
6695
};
6796

6897
export const getSelectedRect = (editable: Locator): Promise<DOMRect> => {

e2e/plain.spec.ts

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ test.describe("type word", () => {
150150

151151
await editable.focus();
152152

153-
expect(await getSelection(editable, true)).toEqual(createSelection());
153+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
154+
createSelection()
155+
);
154156

155157
// Input
156158
const text = "test";
@@ -159,7 +161,7 @@ test.describe("type word", () => {
159161
insertAt(initialValue, text, [0, 0])
160162
);
161163
const textLength = text.length;
162-
expect(await getSelection(editable, true)).toEqual(
164+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
163165
createSelection({ offset: textLength })
164166
);
165167
});
@@ -172,11 +174,13 @@ test.describe("type word", () => {
172174

173175
await editable.focus();
174176

175-
expect(await getSelection(editable, true)).toEqual(createSelection());
177+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
178+
createSelection()
179+
);
176180

177181
// Move caret
178182
await page.keyboard.press("ArrowRight");
179-
expect(await getSelection(editable, true)).toEqual(
183+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
180184
createSelection({ offset: 1 })
181185
);
182186

@@ -187,7 +191,7 @@ test.describe("type word", () => {
187191
insertAt(initialValue, text, [0, 1])
188192
);
189193
const textLength = text.length;
190-
expect(await getSelection(editable, true)).toEqual(
194+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
191195
createSelection({ offset: 1 + textLength })
192196
);
193197
});
@@ -202,7 +206,9 @@ test.describe("type word", () => {
202206

203207
await editable.focus();
204208

205-
expect(await getSelection(editable, true)).toEqual(createSelection());
209+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
210+
createSelection()
211+
);
206212

207213
const client = await page.context().newCDPSession(page);
208214
await client.send("Input.imeSetComposition", {
@@ -223,11 +229,98 @@ test.describe("type word", () => {
223229
insertAt(initialValue, "😂😭", [0, 0])
224230
);
225231
const textLength = "😂😭".length;
226-
expect(await getSelection(editable, true)).toEqual(
232+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
227233
createSelection({ offset: textLength })
228234
);
229235
});
230236
});
237+
238+
test.describe("span as block", () => {
239+
test("on origin", async ({ page }) => {
240+
await page.goto(storyUrl("basics-plain--span-as-block"));
241+
242+
const editable = await getEditable(page);
243+
const initialValue = await getText(editable, { blockTag: "span" });
244+
245+
await editable.focus();
246+
247+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
248+
createSelection()
249+
);
250+
251+
// Input
252+
const text = "test";
253+
await input(editable, text);
254+
expect(await getText(editable, { blockTag: "span" })).toEqual(
255+
insertAt(initialValue, text, [0, 0])
256+
);
257+
const textLength = text.length;
258+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
259+
createSelection({ offset: textLength })
260+
);
261+
});
262+
263+
test("on 1st row", async ({ page }) => {
264+
await page.goto(storyUrl("basics-plain--span-as-block"));
265+
266+
const editable = await getEditable(page);
267+
const initialValue = await getText(editable, { blockTag: "span" });
268+
269+
await editable.focus();
270+
271+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
272+
createSelection()
273+
);
274+
275+
// Move caret
276+
await page.keyboard.press("ArrowRight");
277+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
278+
createSelection({ offset: 1 })
279+
);
280+
281+
// Input
282+
const text = "test";
283+
await input(editable, text);
284+
expect(await getText(editable, { blockTag: "span" })).toEqual(
285+
insertAt(initialValue, text, [0, 1])
286+
);
287+
const textLength = text.length;
288+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
289+
createSelection({ offset: 1 + textLength })
290+
);
291+
});
292+
293+
test("on 2nd row", async ({ page }) => {
294+
await page.goto(storyUrl("basics-plain--span-as-block"));
295+
296+
const editable = await getEditable(page);
297+
const initialValue = await getText(editable, { blockTag: "span" });
298+
299+
await editable.focus();
300+
301+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
302+
createSelection()
303+
);
304+
305+
// Move caret
306+
await page.keyboard.press("ArrowRight");
307+
await page.keyboard.press("ArrowDown");
308+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
309+
createSelection({ line: 1, offset: 1 })
310+
);
311+
312+
// Input
313+
const text = "test";
314+
await input(editable, text);
315+
expect(await getText(editable, { blockTag: "span" })).toEqual(
316+
insertAt(initialValue, text, [1, 1])
317+
);
318+
const textLength = text.length;
319+
expect(await getSelection(editable, { blockTag: "span" })).toEqual(
320+
createSelection({ line: 1, offset: 1 + textLength })
321+
);
322+
});
323+
});
231324
});
232325

233326
test.describe("replace range", () => {

e2e/structured.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ test.describe("smoke node", () => {
3030

3131
// type just before node
3232
await loop(nodeOffset, () => page.keyboard.press("ArrowRight"));
33-
expect(await getSelection(editable, true)).toEqual(
33+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
3434
createSelection({ offset: nodeOffset })
3535
);
3636

@@ -39,20 +39,20 @@ test.describe("smoke node", () => {
3939
expect(await getText(editable)).toEqual(
4040
insertAt(initialValue, char, [0, nodeOffset])
4141
);
42-
expect(await getSelection(editable, true)).toEqual(
42+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
4343
createSelection({ offset: nodeOffset + 1 })
4444
);
4545

4646
// delete
4747
await page.keyboard.press("Backspace");
4848
expect(await getText(editable)).toEqual(initialValue);
49-
expect(await getSelection(editable, true)).toEqual(
49+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
5050
createSelection({ offset: nodeOffset })
5151
);
5252

5353
// type just after node
5454
await page.keyboard.press("ArrowRight");
55-
expect(await getSelection(editable, true)).toEqual(
55+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
5656
createSelection({ offset: nodeOffset + 1 })
5757
);
5858

@@ -61,14 +61,14 @@ test.describe("smoke node", () => {
6161
expect(await getText(editable)).toEqual(
6262
insertAt(initialValue, char, [0, nodeOffset + 1])
6363
);
64-
expect(await getSelection(editable, true)).toEqual(
64+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
6565
createSelection({ offset: nodeOffset + 2 })
6666
);
6767

6868
// delete
6969
await page.keyboard.press("Backspace");
7070
expect(await getText(editable)).toEqual(initialValue);
71-
expect(await getSelection(editable, true)).toEqual(
71+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
7272
createSelection({ offset: nodeOffset + 1 })
7373
);
7474

@@ -77,7 +77,7 @@ test.describe("smoke node", () => {
7777
expect(await getText(editable)).toEqual(
7878
deleteAt(initialValue, 1, [0, nodeOffset])
7979
);
80-
expect(await getSelection(editable, true)).toEqual(
80+
expect(await getSelection(editable, { isSingleline: true })).toEqual(
8181
createSelection({ offset: nodeOffset })
8282
);
8383
});

0 commit comments

Comments
 (0)