Skip to content

Commit beb8d34

Browse files
committed
Fix character insertion bug.
1 parent dce6fb6 commit beb8d34

File tree

5 files changed

+80
-8
lines changed

5 files changed

+80
-8
lines changed

packages/typeit/.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodejs 22.9.0

packages/typeit/__tests__/helpers/insertIntoElement.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,42 @@ describe("an input", () => {
2323
});
2424
});
2525

26+
describe.only("HTML", () => {
27+
it("inserts a character when there's nested HTML", () => {
28+
setHTML`<span id="el">
29+
<span>
30+
<i class="ti-cursor">|</i>
31+
</span>
32+
</span>`;
33+
34+
const el = document.getElementById("el");
35+
36+
insertIntoElement(el, document.createTextNode("x"));
37+
38+
expect(document.body.innerHTML).toEqual(
39+
'<span id="el"><span>x<i class="ti-cursor">|</i></span></span>',
40+
);
41+
});
42+
43+
it("inserts a character when there's deeply nested HTML", () => {
44+
setHTML`<span id="el">
45+
<span>
46+
<p>
47+
<i class="ti-cursor">|</i>
48+
</p>
49+
</span>
50+
</span>`;
51+
52+
const el = document.getElementById("el");
53+
54+
insertIntoElement(el, document.createTextNode("x"));
55+
56+
expect(document.body.innerHTML).toEqual(
57+
'<span id="el"><span><p>x<i class="ti-cursor">|</i></p></span></span>',
58+
);
59+
});
60+
});
61+
2662
describe("plain text", () => {
2763
it("inserts a simple character", () => {
2864
setHTML`<span id="el"><i class="ti-cursor">|</i></span>`;

packages/typeit/package-lock.json

Lines changed: 25 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/typeit/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typeit",
3-
"version": "8.8.6",
3+
"version": "8.8.7",
44
"description": "The most versatile animated typing utility on the planet.",
55
"author": "Alex MacArthur <alex@macarthur.me> (https://macarthur.me)",
66
"license": "GPL-3.0",
@@ -22,7 +22,8 @@
2222
"start": "vite serve examples --host 0.0.0.0",
2323
"test": "vitest run",
2424
"postinstall": "node ./scripts/notice.js",
25-
"prepare": "npm run build"
25+
"prepare": "npm run build",
26+
"format": "prettier --write \"**/*.{js,ts}\""
2627
},
2728
"keywords": [
2829
"javascript",
@@ -39,6 +40,7 @@
3940
"url": "git+https://github.com/alexmacarthur/typeit.git"
4041
},
4142
"devDependencies": {
43+
"prettier": "^3.3.3",
4244
"terser": "^5.36.0",
4345
"typescript": "^5.6.3",
4446
"vite": "^5.4.10",

packages/typeit/src/helpers/insertIntoElement.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,20 @@ let insertIntoElement = (originalTarget: El, character: El) => {
2323
// "originalParent", so always fall back to the default target.
2424
character.originalParent || originalTarget;
2525

26-
target.insertBefore(
27-
character as El,
28-
(select("." + CURSOR_CLASS, target) as Node) || null,
29-
);
26+
let cursorNode = (select("." + CURSOR_CLASS, target) as Node) || null;
27+
28+
/**
29+
* In edge cases, the target may be two levels up from the cursor node,
30+
* making the cursor node's no longer an immediate child, breaking
31+
* the insertBefore method.
32+
*
33+
* During this scenario, reassign the target to the cursor node's parent.
34+
*/
35+
if (cursorNode && cursorNode.parentElement !== target) {
36+
target = cursorNode.parentElement;
37+
}
38+
39+
target.insertBefore(character as El, cursorNode);
3040
};
3141

3242
export default insertIntoElement;

0 commit comments

Comments
 (0)