Skip to content

Commit

Permalink
fix: re-render mathfields on the page when `MathfieldElement.isFuncti…
Browse files Browse the repository at this point in the history
…on` is updated
  • Loading branch information
arnog committed Jun 27, 2024
1 parent 1dc0638 commit f29d923
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@

### Issues Resolved

- When the `MathfieldElement.isFunction` handler is updated, re-render all
the mathfields on the page to take it into account.
- **#2415** A content change event is now dispatched when the value of the
mathfield is changed as a result of switch from LaTeX mode to math mode
by changing the selection.
Expand Down
14 changes: 10 additions & 4 deletions src/core/modes-math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,24 @@ export class MathMode extends Mode {
});
}

const isFunction =
globalThis.MathfieldElement?.isFunction(info.command ?? command) ?? false;
let isFunction: boolean;
try {
isFunction =
globalThis.MathfieldElement?.isFunction(info.command ?? command) ??
false;
} catch (e) {
isFunction = false;
}

if (info.definitionType === 'symbol') {
const result = new Atom({
type: info.type ?? 'mord',
mode: 'math',
command: info.command ?? command,
value: String.fromCodePoint(info.codepoint),
isFunction,
style,
});
if (isFunction) result.isFunction = true;

if (command.startsWith('\\')) result.verbatimLatex = command;
return result;
Expand All @@ -137,9 +143,9 @@ export class MathMode extends Mode {
mode: 'math',
command: info.command ?? command,
value: command,
isFunction,
style,
});
if (isFunction) result.isFunction = true;
if (command.startsWith('\\')) result.verbatimLatex = command;

return result;
Expand Down
17 changes: 2 additions & 15 deletions src/editor-mathfield/mathfield-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ import {
render,
renderSelection,
contentMarkup,
reparse,
} from './render';

import './commands';
Expand Down Expand Up @@ -727,24 +728,10 @@ If you are using Vue, this may be because you are using the runtime-only build o
expandMacro: false,
defaultMode: this.options.defaultMode,
});
if ('macros' in config || this.model.getValue() !== content) {
const selection = this.model.selection;
ModeEditor.insert(this.model, content, {
insertionMode: 'replaceAll',
selectionMode: 'after',
format: 'latex',
silenceNotifications: true,
mode: 'math',
});
const wasSilent = this.model.silenceNotifications;
this.model.silenceNotifications = true;
this.model.selection = selection;
this.model.silenceNotifications = wasSilent;
}
if ('macros' in config || this.model.getValue() !== content) reparse(this);

if (
'value' in config ||
'macros' in config ||
'registers' in config ||
'colorMap' in config ||
'backgroundColorMap' in config ||
Expand Down
31 changes: 31 additions & 0 deletions src/editor-mathfield/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Atom } from '../core/atom-class';
import { applyInterBoxSpacing } from '../core/inter-box-spacing';
import { convertLatexToMarkup } from '../public/mathlive';
import { hashCode } from '../common/hash-code';
import { ModeEditor } from './mode-editor';

export function requestUpdate(
mathfield: _Mathfield | undefined | null,
Expand Down Expand Up @@ -393,3 +394,33 @@ function unionRects(rects: Rect[]): Rect[] {
}
return result;
}

/**
* Re parse the content and rerender.
*
* Used when context changes, for example the definition
* of macros or the `isFunction` global option.
*
* @param mathfield
*/
export function reparse(mathfield: _Mathfield | null): void {
if (!mathfield) return;
const model = mathfield.model;
const selection = model.selection;
const content = Atom.serialize([model.root], {
expandMacro: false,
defaultMode: mathfield.options.defaultMode,
});
ModeEditor.insert(model, content, {
insertionMode: 'replaceAll',
selectionMode: 'after',
format: 'latex',
silenceNotifications: true,
mode: 'math',
});
const wasSilent = model.silenceNotifications;
model.silenceNotifications = true;
model.selection = selection;
model.silenceNotifications = wasSilent;
requestUpdate(mathfield);
}
6 changes: 5 additions & 1 deletion src/public/mathfield-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
isTouchCapable,
} from '../ui/utils/capabilities';
import { resolveUrl } from '../common/script-url';
import { requestUpdate } from '../editor-mathfield/render';
import { reparse, requestUpdate } from '../editor-mathfield/render';
import { reloadFonts, loadFonts } from '../core/fonts';
import { defaultSpeakHook } from '../editor/speech';
import { defaultReadAloudHook } from '../editor/speech-read-aloud';
Expand Down Expand Up @@ -1097,6 +1097,10 @@ export class MathfieldElement extends HTMLElement implements Mathfield {

static set isFunction(value: (command: string) => boolean) {
this._isFunction = value;

document.querySelectorAll('math-field').forEach((el) => {
if (el instanceof MathfieldElement) reparse(el._mathfield);
});
}

static async loadSound(
Expand Down
32 changes: 14 additions & 18 deletions test/smoke/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ <h1>Smoke Test</h1>
</ul>
</header>
<main>
<math-field id="mf">\lnot p</math-field>
<math-field id="mf">f\left(x\right)\mathop{f}\left(x\right)</math-field>
<!-- <math-field id="mf">\mathrm{Hypot}\left(\textcolor{red}{#?},{#?}\right)</math-field> -->
<!-- <math-field id="mf"
>\left(r+s+\right)+\sqrt{x+1}=\frac{ab+cd}{1243+def}</math-field
Expand Down Expand Up @@ -156,13 +156,13 @@ <h2>Latex to Speakable Text</h2>

// MathfieldElement.computeEngine = ce;

MathfieldElement.computeEngine.latexOptions = {
...MathfieldElement.computeEngine.latexOptions,
parseUnknownIdentifier: (s) =>
/^[a-zA-Z]+$/.test(s) ? "function" : "unknown",
};
// MathfieldElement.computeEngine.latexOptions = {
// ...MathfieldElement.computeEngine.latexOptions,
// parseUnknownIdentifier: (s) =>
// /^[a-zA-Z]+$/.test(s) ? "function" : "unknown",
// };

MathfieldElement.computeEngine.declare("f", "Functions");
// MathfieldElement.computeEngine.declare("f", "Functions");

// mathVirtualKeyboard.setKeycap('[*]', {
// latex: '\\times',
Expand Down Expand Up @@ -802,19 +802,14 @@ <h2>Latex to Speakable Text</h2>
}


mf.addEventListener('contextmenu', (ev) => {
console.log('Context menu', ev);
ev.preventDefault();
}, { capture: true });
// mf.addEventListener('contextmenu', (ev) => {
// console.log('Context menu', ev);
// ev.preventDefault();
// }, { capture: true });

window.MathfieldElement.isFunction = (s) => /^[f-h]+$/.test(s);

// setupMathfield(mf);
window.addEventListener('message', (ev) => {
console.log('Message', ev.data);
});
mathVirtualKeyboard.addEventListener('math-virtual-keyboard-command', (ev) => {
console.log('Command', ev.detail);
});
mf.addEventListener('mount', () => {
console.log('Mounted');

Expand Down Expand Up @@ -850,8 +845,9 @@ <h2>Latex to Speakable Text</h2>

// mf.scriptDepth = [0, 0];


// mf.onInlineShortcut = (_mf, s) =>
// /^[a-zA-Z]+$/.test(s) ? `\\mathrm{${s}}` : '';
// /^[a-zA-Z]+$/.test(s) ? `\\mathop{${s}}` : '';
// mf.onInlineShortcut = (_mf, s) => {
// if (/^[a-zA-Z][a-zA-Z0-9]*'?(_[a-zA-Z0-9]+'?)?$/.test(s)) {
// const m = s.match(/^([a-zA-Z]+)([0-9]+)$/);
Expand Down

0 comments on commit f29d923

Please sign in to comment.