Skip to content

Commit

Permalink
Merge pull request #304 from desmosinc/jared/static-saneKeyboardEvents
Browse files Browse the repository at this point in the history
Support overrideKeystroke on static math
  • Loading branch information
jared-hughes authored Sep 20, 2024
2 parents dd34480 + 57ff064 commit 1eb8dd0
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/commands/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,12 +708,14 @@ API.StaticMath = function (APIClasses: APIClasses) {

__mathquillify(opts: ConfigOptions, _interfaceVersion: number) {
this.config(opts as MathQuill.v3.Config);
// `mathquillify` calls `createTextarea`
super.mathquillify('mq-math-mode');
this.__controller.setupStaticField();
if (this.__options.mouseEvents) {
this.__controller.addMouseEventListener();
this.__controller.staticMathTextareaEvents();
}
// The textarea is initialized (`createTextarea` called) by this point.
this.__controller.staticMathTextareaEvents();
return this;
}
constructor(el: Controller) {
Expand Down
12 changes: 6 additions & 6 deletions src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,15 @@ class ControllerBase {
);
}

getTextareaOrThrow() {
var textarea = this.textarea;
if (!textarea) throw new Error('expected a textarea');
getTextarea() {
const textarea = this.textarea;
pray('textarea initialized', textarea);
return textarea;
}

getTextareaSpanOrThrow() {
var textareaSpan = this.textareaSpan;
if (!textareaSpan) throw new Error('expected a textareaSpan');
getTextareaSpan() {
const textareaSpan = this.textareaSpan;
pray('textareaSpan initialized', textareaSpan);
return textareaSpan;
}

Expand Down
4 changes: 2 additions & 2 deletions src/publicapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,12 @@ function getInterface(v: number): MathQuill.v3.API | MathQuill.v1.API {
return this;
}
focus() {
this.__controller.getTextareaOrThrow().focus();
this.__controller.getTextarea().focus();
if (this.__controller.editable) this.__controller.scrollHoriz();
return this;
}
blur() {
this.__controller.getTextareaOrThrow().blur();
this.__controller.getTextarea().blur();
return this;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/mouse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class Controller_mouse extends Controller_latex {
var ctrlr = root.controller,
cursor = ctrlr.cursor,
blink = cursor.blink;
var textarea = ctrlr.getTextareaOrThrow();
var textarea = ctrlr.getTextarea();

e.preventDefault(); // doesn't work in IE≤8, but it's a one-line fix:
(e.target as any).unselectable = true; // http://jsbin.com/yagekiji/1 // TODO - no idea what this unselectable property is
Expand Down
12 changes: 12 additions & 0 deletions src/services/saneKeyboardEvents.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ var saneKeyboardEvents = (function () {
everyTick.trigger(e);
}

if (controller.KIND_OF_MQ === 'StaticMath') {
controller.addTextareaEventListeners({
keydown: (evt) => {
// The name `overrideKeystroke` matches the API for editable math,
// but it is overriding nothing. It replaces nothing with something.
controller.options.overrideKeystroke?.(getMQKeyName(evt!), evt);
}
});

return { select };
}

if (controller.options && controller.options.disableCopyPaste) {
controller.addTextareaEventListeners({
keydown: onKeydown,
Expand Down
22 changes: 11 additions & 11 deletions src/services/textarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Controller extends Controller_scrollHoriz {
this.selectFn(latex);
}

/** Requires `this.textarea` to be initialized. */
staticMathTextareaEvents() {
var ctrlr = this;
this.removeTextareaEventListener('cut');
Expand All @@ -87,18 +88,16 @@ class Controller extends Controller_scrollHoriz {

this.addStaticFocusBlurListeners();

ctrlr.selectFn = function (text: string) {
const textarea = ctrlr.getTextareaOrThrow();
if (!(textarea instanceof HTMLTextAreaElement)) return;
textarea.value = text;
if (text) textarea.select();
};
const textarea = this.getTextarea();
const { select } = saneKeyboardEvents(textarea, this);
this.selectFn = select;
}

/** Requires `this.textarea` to be initialized. */
editablesTextareaEvents() {
var ctrlr = this;
const textarea = ctrlr.getTextareaOrThrow();
const textareaSpan = ctrlr.getTextareaSpanOrThrow();
const textarea = ctrlr.getTextarea();
const textareaSpan = ctrlr.getTextareaSpan();

if (this.options.version < 3) {
const $ = this.options.assertJquery();
Expand All @@ -118,10 +117,11 @@ class Controller extends Controller_scrollHoriz {
this.addEditableFocusBlurListeners();
this.updateMathspeak();
}

unbindEditablesEvents() {
var ctrlr = this;
const textarea = ctrlr.getTextareaOrThrow();
const textareaSpan = ctrlr.getTextareaSpanOrThrow();
const textarea = ctrlr.getTextarea();
const textareaSpan = ctrlr.getTextareaSpan();

this.selectFn = function (text: string) {
if (!(textarea instanceof HTMLTextAreaElement)) return;
Expand Down Expand Up @@ -203,7 +203,7 @@ class Controller extends Controller_scrollHoriz {
var mathspeak = ctrlr.root.mathspeak().trim();
this.aria.clear();

const textarea = ctrlr.getTextareaOrThrow();
const textarea = ctrlr.getTextarea();
// For static math, provide mathspeak in a visually hidden span to allow screen readers and other AT to traverse the content.
// For editable math, assign the mathspeak to the textarea's ARIA label (AT can use text navigation to interrogate the content).
// Be certain to include the mathspeak for only one of these, though, as we don't want to include outdated labels if a field's editable state changes.
Expand Down
11 changes: 11 additions & 0 deletions test/unit/publicapi.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,17 @@ suite('Public API', function () {
trigger.keydown(mq.el().querySelector('textarea'), 'ArrowLeft');
assert.equal(key, 'Left');
});
test('can intercept key events on static', function () {
var mq = MQ.StaticMath($('<span>').appendTo('#mock')[0], {
overrideKeystroke: function (_key, evt) {
key = _key;
}
});
var key;

trigger.keydown(mq.el().querySelector('textarea'), 'ArrowLeft');
assert.equal(key, 'Left');
});
test('cut is async', function (done) {
var mq = MQ.MathField($('<span>').appendTo('#mock')[0], {
onCut: function () {
Expand Down

0 comments on commit 1eb8dd0

Please sign in to comment.