Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/mathquill.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ declare namespace MathQuill {
statelessClipboard?: boolean;
onPaste?: () => void;
onCut?: () => void;
overridePaste?: (event?: ClipboardEvent) => void;
overrideCopy?: (event?: ClipboardEvent) => void;
overrideCut?: (event?: ClipboardEvent) => void;
overridePaste?: (event?: ClipboardEvent) => boolean;
overrideCopy?: (event?: ClipboardEvent) => boolean;
overrideCut?: (event?: ClipboardEvent) => boolean;
overrideTypedText?: (text: string) => void;
overrideKeystroke?: (key: string, event: KeyboardEvent) => void;
autoOperatorNames?: string;
Expand Down
6 changes: 3 additions & 3 deletions src/publicapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ class Options {
disableCopyPaste?: boolean;
statelessClipboard?: boolean;
logAriaAlerts?: boolean;
overridePaste?: (event?: ClipboardEvent) => void;
overrideCopy?: (event?: ClipboardEvent) => void;
overrideCut?: (event?: ClipboardEvent) => void;
overridePaste?: (event?: ClipboardEvent) => boolean;
overrideCopy?: (event?: ClipboardEvent) => boolean;
overrideCut?: (event?: ClipboardEvent) => boolean;
onPaste?: () => void;
onCut?: () => void;
overrideTypedText?: (text: string) => void;
Expand Down
32 changes: 23 additions & 9 deletions src/services/saneKeyboardEvents.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,8 @@ var saneKeyboardEvents = (function () {

const clipboardEvent = e instanceof ClipboardEvent ? e : undefined;
if (clipboardEvent && controller.options?.overridePaste) {
controller.options.overridePaste(clipboardEvent);
return;
const earlyReturn = controller.options.overridePaste(clipboardEvent);
if (earlyReturn) return;
}

everyTick.listen(function pastedText() {
Expand All @@ -366,6 +366,21 @@ var saneKeyboardEvents = (function () {
everyTick.trigger(e);
}

function updateClipboardData(e: ClipboardEvent | undefined) {
if (e?.clipboardData) {
const selection = controller.exportLatexSelection().selection;
if (selection.startIndex !== selection.endIndex) {
const text = selection.latex.slice(
selection.startIndex,
selection.endIndex
);
e.clipboardData.setData('text/plain', text);
e.clipboardData.setData('application/x-latex', text);
e.preventDefault();
}
}
}

if (controller.KIND_OF_MQ === 'StaticMath') {
controller.addTextareaEventListeners({
keydown: (evt) => {
Expand Down Expand Up @@ -406,9 +421,10 @@ var saneKeyboardEvents = (function () {
const clipboardEvent =
evt instanceof ClipboardEvent ? evt : undefined;
if (clipboardEvent && controller.options?.overrideCut) {
controller.options.overrideCut(clipboardEvent);
return;
const earlyReturn = controller.options.overrideCut(clipboardEvent);
if (earlyReturn) return;
}
updateClipboardData(clipboardEvent);
everyTick.listenOnce(function () {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think maybe jared addressed this, but it seems odd to me to do both the controller.cut() and the updateClipboardData() here. I don't really feel like I have a good handle on what's going to happen in practice. Is the updateClipboardData() going to work or not? If it does, then what do we need the controller.cut() for? Is the controller.cut() going to overwrite whatever the updateClipboardData() does?

My main concern here is just making sure all mqs that don't use the override methods continue to work correctly. I remember recently digging into copy/paste in the knox acceptance tests and realizing that the timing of things is really subtle.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

In the previous code when you did a cut, you were actually using the browser default behavior and cutting text out of a textarea while MQ would remove the latex from display. I think this is reason for the subtle timing weirdness. The browser has to finish the cut from the textarea before MQ can clean up everything.

In this code, we're manually updating the clipboard data, calling preventDefault() so the textarea thing is irrelevant, but controller.cut() is still necessary to have MQ remove the latex. I think this simplifies the timing, but I'm leaving the extra tick around the cut just to avoid unforeseen regressions.

What do you think?

controller.cut();
});
Expand All @@ -417,12 +433,10 @@ var saneKeyboardEvents = (function () {
const clipboardEvent =
evt instanceof ClipboardEvent ? evt : undefined;
if (clipboardEvent && controller.options?.overrideCopy) {
controller.options.overrideCopy(clipboardEvent);
return;
const earlyReturn = controller.options.overrideCopy(clipboardEvent);
if (earlyReturn) return;
}
everyTick.listenOnce(function () {
controller.copy();
});
updateClipboardData(clipboardEvent);
},
paste: onPaste,
input: onInput
Expand Down