Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move most of perseus - util.ts into perseus-core - util.ts #2089

Open
wants to merge 1 commit into
base: LEMS-2737-2/utils
Choose a base branch
from

Conversation

handeyeco
Copy link
Contributor

@handeyeco handeyeco commented Jan 9, 2025

Summary:

I couldn't move the whole of util.ts from perseus to perseus-core because of some of its dependencies, but I moved as much as I could. Most of this is just changing imports.

Issue: LEMS-2737

@handeyeco handeyeco self-assigned this Jan 9, 2025
@handeyeco handeyeco changed the title move utils from perseus to core Move most of perseus - util.ts into perseus-core - util.ts Jan 9, 2025
Copy link
Contributor

github-actions bot commented Jan 9, 2025

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (405428c) and published it to npm. You
can install it using the tag PR2089.

Example:

yarn add @khanacademy/perseus@PR2089

If you are working in Khan Academy's webapp, you can run:

./dev/tools/bump_perseus_version.sh -t PR2089

Copy link
Contributor

github-actions bot commented Jan 9, 2025

Size Change: +505 B (+0.03%)

Total Size: 1.47 MB

Filename Size Change
packages/perseus-core/dist/es/index.js 28.5 kB +5.43 kB (+23.49%) 🚨
packages/perseus-editor/dist/es/index.js 688 kB +25 B (0%)
packages/perseus/dist/es/index.js 402 kB -4.95 kB (-1.22%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 39 kB
packages/keypad-context/dist/es/index.js 760 B
packages/kmath/dist/es/index.js 83.1 kB
packages/math-input/dist/es/index.js 78 kB
packages/math-input/dist/es/strings.js 1.79 kB
packages/perseus-linter/dist/es/index.js 22.2 kB
packages/perseus-score/dist/es/index.js 103 kB
packages/perseus/dist/es/strings.js 4.84 kB
packages/pure-markdown/dist/es/index.js 3.67 kB
packages/simple-markdown/dist/es/index.js 12.5 kB

compressed-size-action

@handeyeco handeyeco requested review from a team January 9, 2025 20:49
Copy link
Collaborator

@jeremywiebe jeremywiebe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I'd just suggest moving some UI functions back into Perseus if we can.

unescapeMathMode,
random,
deepClone,
} as const;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's your appetite like for switching these to simple named exports instead of bundling them in an object first? We could still export them as a Util namespace in the top-level index.ts so the imports don't change...

left: number;
};

type TouchHandlers = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having references to UI concepts in perseus-score raises a warning flag for me. What do you think of leaving anything to do with UI (touch, event handling, anything touching window).

function parseQueryString(query: string): QueryParams {
// TODO(jangmi, CP-3340): Use withLocation to access SSR safe location.
// eslint-disable-next-line no-restricted-syntax
query = query || window.location.search.substring(1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is safe to move, but we should probably drop the || window... bit as that won't be safe in a non-browser env.

Comment on lines +496 to +624
for (let i = 0; i < len; i++) {
if (
event.changedTouches[i].identifier ===
touchHandlers.currentTouchIdentifier
) {
touchOrEvent = event.changedTouches[i];
}
}
} else {
touchOrEvent = event;
}

const isEndish =
event.type === "touchend" || event.type === "touchcancel";
if (touchOrEvent && isEndish) {
touchHandlers.pointerDown = false;
touchHandlers.currentTouchIdentifier = null;
}
} else {
// touchstart or mousedown
touchHandlers.pointerDown = true;
if (event.changedTouches) {
touchOrEvent = event.changedTouches[0];
touchHandlers.currentTouchIdentifier = touchOrEvent.identifier;
} else {
touchOrEvent = event;
}
}

if (touchOrEvent) {
return {
left: touchOrEvent.pageX,
top: touchOrEvent.pageY,
};
}
}

// Older browsers don't support passive events and so we need to feature-
// detect them and do event subscription differently for them.
// See: orderer.jsx
const supportsPassiveEvents: () => boolean = () => {
// Test via a getter in the options object to see if the passive
// property is accessed
try {
const opts = Object.defineProperty({}, "passive", {
get: function () {
supportsPassive = true;
},
});
// @ts-expect-error - TS2769 - No overload matches this call.
window.addEventListener("testPassive", null, opts);
// @ts-expect-error - TS2769 - No overload matches this call.
window.removeEventListener("testPassive", null, opts);
} catch {
// Intentionally left empty!
}

return supportsPassive;
};

/**
* Gets the word right before where the textarea cursor is
*
* @param {Element} textarea - The textarea DOM element
* @return {JSON} - An object with the word and its starting and ending positions in the textarea
*/
function getWordBeforeCursor(textarea: HTMLTextAreaElement): WordAndPosition {
const text = textarea.value;

const endPos = textarea.selectionStart - 1;
const startPos =
Math.max(
text.lastIndexOf("\n", endPos),
text.lastIndexOf(" ", endPos),
) + 1;

return {
string: text.substring(startPos, endPos + 1),
pos: {
start: startPos,
end: endPos,
},
};
}

/**
* Moves the textarea cursor at the specified position
*
* @param {Element} textarea - The textarea DOM element
* @param {int} pos - The position where the cursor will be moved
*/
function moveCursor(textarea: HTMLTextAreaElement, pos: number): void {
textarea.selectionStart = pos;
textarea.selectionEnd = pos;
}

const textarea = {
getWordBeforeCursor,
moveCursor,
} as const;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all feels like it should stay in perseus.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants