Skip to content

Commit

Permalink
Fix bug caused by passing move() value that's out of range.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmacarthur committed Sep 1, 2021
1 parent 8e51271 commit 61377c8
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 16 deletions.
47 changes: 47 additions & 0 deletions __tests__/chainable-methods/move.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import TypeIt from "../../src/TypeIt";
import * as wait from "../../src/helpers/wait";
import * as repositionCursor from "../../src/helpers/repositionCursor";

beforeEach(() => {
jest.clearAllMocks();
Expand Down Expand Up @@ -68,3 +69,49 @@ describe("timeouts fire correctly", () => {
.go();
});
});

describe("moves only within range", () => {
let repositionCursorSpy;

beforeEach(() => {
setHTML`<div>
<span id="element"></span>
</div>`;

repositionCursorSpy = jest.spyOn(repositionCursor, "default");
});

it("bottom end of range", (done) => {
new TypeIt("#element", {
speed: 0,
afterComplete: () => {
expect(repositionCursorSpy.mock.calls).toEqual([
[expect.anything(), expect.anything(), expect.anything(), 0],
[expect.anything(), expect.anything(), expect.anything(), 0],
]);
done();
},
})
.type("Hi!")
.move(2) // Number of steps is out of range of printed characters.
.go();
});

it("top end of range", (done) => {
new TypeIt("#element", {
speed: 0,
afterComplete: () => {
expect(repositionCursorSpy.mock.calls).toEqual([
[expect.anything(), expect.anything(), expect.anything(), 1],
[expect.anything(), expect.anything(), expect.anything(), 2],
[expect.anything(), expect.anything(), expect.anything(), 3],
[expect.anything(), expect.anything(), expect.anything(), 3],
]);
done();
},
})
.type("Hi!")
.move(-4) // Number of steps is out of range of printed characters.
.go();
});
});
2 changes: 0 additions & 2 deletions __tests__/helpers/__snapshots__/repositionCursor.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ exports[`Moves cursor three back and two forward. 1`] = `"<span id=\\"el\\">1234
exports[`Moves cursor three steps back. 1`] = `"<span id=\\"el\\">12<i id=\\"cursor\\">|</i>345</span>"`;
exports[`Stops moving when at beginning of string. 1`] = `"<span id=\\"el\\"><i id=\\"cursor\\">|</i>12345</span>"`;
exports[`Stops moving when at end of string. 1`] = `"<span id=\\"el\\">12345<i id=\\"cursor\\">|</i></span>"`;
25 changes: 25 additions & 0 deletions __tests__/helpers/calculateCursorSteps.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,28 @@ describe("string has nested HTML", () => {
expect(result).toEqual(19);
});
});

describe("arg is outside bounds", () => {
it("returns zero when overshooting back", async () => {
const el = document.querySelector("#el");

await new Promise((resolve) => {
new TypeIt(el, {
strings: "Hi, <strong class='t'>Bob!</strong>",
speed: 0,
afterComplete: () => {
return resolve();
},
}).go();
});

const result = calculateCursorSteps({
el,
move: null,
cursorPos: 8,
to: "end",
});

expect(result).toEqual(-8);
});
});
6 changes: 0 additions & 6 deletions __tests__/helpers/repositionCursor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ test("Moves cursor three back and two forward.", () => {
expect(document.body.innerHTML).toMatchSnapshot();
});

test("Stops moving when at beginning of string.", () => {
repositionCursor(element, allCharacters, cursor, 100);

expect(document.body.innerHTML).toMatchSnapshot();
});

test("Stops moving when at end of string.", () => {
repositionCursor(element, allCharacters, cursor, -100);

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typeit",
"version": "8.0.1",
"version": "8.0.2",
"description": "The most versatile animated typing utility on the planet.",
"author": "Alex MacArthur <[email protected]> (https://macarthur.me)",
"license": "GPL-3.0",
Expand Down
8 changes: 7 additions & 1 deletion src/TypeIt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import handleFunctionalArg from "./helpers/handleFunctionalArg";
import isNumber from "./helpers/isNumber";
import insertIntoElement from "./helpers/insertIntoElement";
import isInput from "./helpers/isInput";
import updateCursorPosition from "./helpers/updateCursorPosition";
import merge from "./helpers/merge";
import removeNode from "./helpers/removeNode";
import removeEmptyElements from "./helpers/removeEmptyElements";
Expand Down Expand Up @@ -296,7 +297,12 @@ export default function TypeIt(
});

let moveCursor = () => {
_cursorPosition += numberOfSteps < 0 ? -1 : 1;
_cursorPosition = updateCursorPosition(
numberOfSteps < 0 ? -1 : 1,
_cursorPosition,
_getAllChars()
);

repositionCursor(_element, _getAllChars(), _cursor, _cursorPosition);
};

Expand Down
8 changes: 2 additions & 6 deletions src/helpers/repositionCursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ export default (
element: Node,
allChars: any[],
cursor: Node,
cursorPosition: number
newCursorPosition: number
): void => {
// Guarantee that the new cursor position is never greater than
// the number of characters we're dealing with.
let characterIndex = Math.min(cursorPosition, allChars.length);

let nodeToInsertBefore = allChars[characterIndex - 1];
let nodeToInsertBefore = allChars[newCursorPosition - 1];

element = nodeToInsertBefore?.parentNode || element;

Expand Down
12 changes: 12 additions & 0 deletions src/helpers/updateCursorPosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const updateCursorPosition = (
steps: number,
cursorPosition: number,
printedCharacters: Element[]
) => {
return Math.min(
Math.max(cursorPosition + steps, 0),
printedCharacters.length
);
};

export default updateCursorPosition;

0 comments on commit 61377c8

Please sign in to comment.