Changelog
0.90.11 2023-03-31
Changelog
0.90.0 2023-03-19
This release contains several breaking changes. As much as possible I try to avoid introducing breaking changes, but there was an accumulation of issues that required some breaking change and I figured I would introduce them all at once:
New implementation of the \placeholder{}
command for "fill-in-the-blank"
feature. Thank you to James Mullen (https://github.com/wildyellowfin) for this
contribution.
Previously, each placeholder was an embedded mathfield inside a "root" mathfield. The placeholders are now special editable regions of a read-only mathfield.
This improves their layout (for example a placeholder numerator is now
displayed at the correct size) and simplify their interaction. When used as a
"fill-in-the-blank", set the mathfield to readonly, and specify an ID with the
placeholder, i.e. \placeholder[id]{value}
. In this situation these
placeholders are called "prompts".
The mf.getPlaceholderField()
function has been replaced with
mf.getPromptValue()
Use mf.setPromptValue()
to change the content of a prompt.
Use mf.getPrompts()
to get an array of the ids of all the prompts in the
expression.
Prompts can be either in a correct, incorrect or indeterminate state. In
correct or incorrect state, their appearance changes to reflect their state.
Use mf.setPromptState()
to flag a prompt as being correct or incorrect.
mf.setPromptState()
can also be used to mark a prompt as no longer being
editable.
Previously the virtual keyboard was shared amongst mathfield instances if the
makeSharedVirtualKeyboard()
function was called or the
use-shared-virtual-keyboard
attribute was set on a mathfield. Otherwise a
virtual keyboard instance was created for each mathfield in the document.
The virtual keyboard is now always shared.
The virtual keyboard global instance can be accessed as
window.mathVirtualKeyboard
or just mathVirtualKeyboard
. Its value
implements VirtualKeyboardInterface
instance, same as was previously
returned by makeSharedVirtualKeyboard()
.
The options related to the virtual keyboard should now be set on the global
shared virtual keyboard, using window.mathVirtualKeyboard
instead of on
mathfield instances.
The MathLive virtual keyboard API (offered by the window.mathVirtualKeyboard
property) has changed to be consistent with the
W3C Virtual Keyboard API.
This includes adding a show()
and hide()
functions, and a boundingRect
property to VirtualKeyboardInterface
.
A geometrychange
event is dispatched when the size of the keyboard changes.
In addition, the MathfieldElement.virtualKeyboardMode
property is now called
MathfieldElement.mathVirtualKeyboardPolicy
and can take a value of "auto"
or "manual"
.
A value of "manual"
corresponds to the previous virtualKeyboardMode
value
of "off"
, that is the virtual keyboard is not displayed automatically and
must be displayed programmatically.
The value "onfocus"
is no longer supported. To implement the behavior
previously provided by this value:
mf.addEventListener('focusin', () => mathVirtualKeyboard.show());
If mathVirtualKeyboardPolicy
is set to "auto"
the virtual keyboard is
displayed automatically when a mathfield is focused on a touch-enabled device.
The virtual keyboard customization API has been simplified.
Before:
const MINIMAL_LAYER = [
minimal: {
rows: [
[
{latex: "+"}, {latex: "-"}, {latex: "\\times"},
{latex: "\\frac{#@}{#?}"}, {latex: "="}, {latex: "."},
{latex: "("}, {latex: ")"}, {latex: "\\sqrt{#0}"},
{latex: "#@^{#?}"}
],
[
{latex: "1"}, {latex: "2"}, {latex: "3"}, {latex: "4"},
{latex: "5"}, {latex: "6"}, {latex: "7"}, {latex: "8"},
{latex: "9"}, {latex: "0"},
]
]
}];
const MINIMAL_KEYBOARD = {
'minimal': {
label: 'Minimal',
layer: 'minimal',
},
};
mf.setOptions({
customVirtualKeyboardLayers: MINIMAL_LAYER,
customVirtualKeyboards: MINIMAL_KEYBOARD,
virtualKeyboards: 'minimal',
});
Now:
mathVirtualKeyboard.layouts = {
rows: [
[
'+',
'-',
'\\times',
'\\frac{#@}{#?}',
'=',
'.',
'(',
')',
'\\sqrt{#0}',
'#@^{#?}',
],
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
],
};
To change the alphabetic layout:
Before:
mf.setOptions({ virtualKeyboardLayout: 'azerty' });
Now:
mathVirtualKeyboard.alphabeticLayout = 'azerty';
The "roman"
virtual keyboard is now called "alphabetic"
The virtualKeyboardToolbar
option is now mathVirtualKeyboard.actionToolbar
The virtualKeyboardContainer
option is now mathVirtualKeyboard.container
The virtual keyboard toggle glyph can no longer be customized.
The virtual keyboard toggle button is displayed by default if the content of mathfield can be modified.
The display of the toggle button is independent of the
mathVirtualKeyboardPolicy
.
Using the math-field::part(virtual-keyboard-toggle)
CSS selector, a
display: none
CSS attribute can be used to hide the virtual keyboard toggle
if desired. To replicate the previous default behavior, where the toggle was
displayed on touch-enabled devices, use:
@media not (pointer: coarse) {
math-field::part(virtual-keyboard-toggle) {
display: none;
}
}
The "alt-keys" of the virtual keyboard are now called "variants". The
data-alt-keys
attribute is now data-variants
Previously all the options to configure a mathfield could be changed using
mf.setOptions({...})
. Some of these options affected a specific mathfield
instance, while others affected all mathfields on the page.
The options that affect all mathfields are now static properties of the
MathfieldElement
global. The options that affect the virtual keyboard are
properties of the mathVirtualKeyboard
global singleton. The options specific
to a mathfield are now properties or attribute of this element.
For example:
Before:
mf.setOptions({ soundsDirectory: null });
Now:
MathfieldElement.soundsDirectory = null;
| Before | Now |
| :-------------------------------------------------- | :--------------------------------------------------------------------------- |
| mf.setOptions({defaultMode: ...})
| mf.defaultMode = ...
|
| mf.setOptions({letterShapeStyle: ...})
| mf.letterShapeStyle = ...
|
| mf.setOptions({horizontalSpacingScale: ...})
| Removed. Use "thinmuskip"
, "medmuskip"
, and "thickmuskip"
registers ', |
| mf.setOptions({macros: ...})
| mf.macros = ...
|
| mf.setOptions({registers: ...})
| mf.registers = ...
|
| mf.setOptions({backgroundColorMap: ...})
| mf.backgroundColorMap = ...
|
| mf.setOptions({colorMap: ...})
| mf.colorMap = ...
|
| mf.setOptions({enablePopover: ...})
| mf.popoverPolicy = ...
|
| mf.setOptions({mathModeSpace: ...})
| mf.mathModeSpace = ...
|
| mf.setOptions({placeholderSymbol: ...})
| mf.placeholderSymbol = ...
|
| mf.setOptions({readOnly: ...})
| mf.readOnly = ...
|
| mf.setOptions({removeExtraneousParentheses: ...})
| mf.removeExtraneousParentheses = ...
|
| mf.setOptions({scriptDepth: ...})
| mf.scriptDepth = ...
|
| mf.setOptions({smartFence: ...})
| mf.smartFence = ...
|
| mf.setOptions({smartMode: ...})
| mf.smartMode = ...
|
| mf.setOptions({smartSuperscript: ...})
| mf.smartSuperscript = ...
|
| mf.setOptions({inlineShortcutTimeout: ...})
| mf.inlineShortcutTimeout = ...
|
| mf.setOptions({inlineShortcuts: ...})
| mf.inlineShortcuts = ...
|
| mf.setOptions({keybindings: ...})
| mf.keybindings = ...
|
| mf.setOptions({virtualKeyboardMode: ...})
| mf.mathVirtualKeyboardPolicy = ...
|
| mf.setOptions({customVirtualKeyboardLayers: ...})
| mathVirtualKeyboard.layouts.layers = ...
|
| mf.setOptions({customVirtualKeyboards: ...})
| mathVirtualKeyboard.layouts = ...
|
| mf.setOptions({keypressSound: ...})
| mathVirtualKeyboard.keypressSound = ...
|
| mf.setOptions({keypressVibration: ...})
| mathVirtualKeyboard.keypressVibration = ...
|
| mf.setOptions({plonkSound: ...})
| mathVirtualKeyboard.plonkSound = ...
|
| mf.setOptions({virtualKeyboardContainer: ...})
| mathVirtualKeyboard.container = ...
|
| mf.setOptions({virtualKeyboardLayout: ...})
| mathVirtualKeyboard.alphabeticLayout = ...
|
| mf.setOptions({virtualKeyboardTheme: ...})
| No longer supported |
| mf.setOptions({virtualKeyboardToggleGlyph: ...})
| No longer supported |
| mf.setOptions({virtualKeyboardToolbar: ...})
| mathVirtualKeyboard.actionToolbar = ...
|
| mf.setOptions({virtualKeyboards: ...})
| Use mathVirtualKeyboard.layouts
|
| mf.setOptions({speechEngine: ...})
| MathfieldElement.speechEngine
|
| mf.setOptions({speechEngineRate: ...})
| MathfieldElement.speechEngineRate
|
| mf.setOptions({speechEngineVoice: ...})
| MathfieldElement.speechEngineVoice
|
| mf.setOptions({textToSpeechMarkup: ...})
| MathfieldElement.textToSpeechMarkup
|
| mf.setOptions({textToSpeechRules: ...})
| MathfieldElement.textToSpeechRules
|
| mf.setOptions({textToSpeechRulesOptions: ...})
| MathfieldElement.textToSpeechRulesOptions
|
| mf.setOptions({readAloudHook: ...})
| MathfieldElement.readAloudHook
|
| mf.setOptions({speakHook: ...})
| MathfieldElement.speakHook
|
| mf.setOptions({computeEngine: ...})
| MathfieldElement.computeEngine
|
| mf.setOptions({fontsDirectory: ...})
| MathfieldElement.fontsDirectory
|
| mf.setOptions({soundsDirectory: ...})
| MathfieldElement.soundsDirectory
|
| mf.setOptions({createHTML: ...})
| MathfieldElement.createHTML
|
| mf.setOptions({onExport: ...})
| MathfieldElement.onExport
|
| mf.setOptions({onInlineShortcut: ...})
| MathfieldElement.onInlineShortcut
|
| mf.setOptions({locale: ...})
| MathfieldElement.locale = ...
|
| mf.setOptions({strings: ...})
| MathfieldElement.strings = ...
|
| mf.setOptions({decimalSeparator: ...})
| MathfieldElement.decimalSeparator = ...
|
| mf.setOptions({fractionNavigationOrder: ...})
| MathfieldElement.fractionNavigationOrder = ...
|
<textarea>
the <math-field>
tag now has a default
display style of "inline". You can change the display style to "block" using a
CSS rule.<math-field>
tag now has some default styling, including a background
and border, consistent with a <textarea>
element. You can override this
styling by defining CSS rules for the math-field
selector.horizontalSpacingScale
has been removed. It
is replaced by the standard TeX registers\thinmuskip
, \medmuskip
and
\thickmuskip
.<script>
tag inside the mathfield, as JSON data structure. This is no longer
supported.<style>
tag inside the mathfield. This is no
longer supported. Use custom CSS variables or part
selectors to apply custom
styling to the mathfield.disabled
and readonly
attributes and the user-select
CSS property
are now consistent with <textarea>
:
readonly
mathfield is still focusabledisabled
mathfield is not focusablereadonly
or disabled
mathfield can be selected, unless
the contenteditable
attribute is set to "false"
and the user-select
CSS property is set to "none"
. (fixes #1136)<p>
element.<textarea>
, click
events are not dispatched when a
disabled <math-element>
is clicked.theme
attribute to the container of the keyboard, for example
<body theme="dark">
or <body theme="light">
.\char
commands were in an expression, they would all
have the same argument when serialized\pm
command was incorrectmf.setValue()
did not affect fill-in-the-blank sectionsChangelog
0.89.4 2023-02-27
Changelog
0.89.3 2023-02-27
<textarea>
, the keyboard events are now captured by
a content editable <span>
.inputType
property as the data
property of "input"
and "beforeinput"
events.
WebKit/Safari erroneously strip the inputType
property.Changelog
0.89.2 2023-02-17
/dist
directory with a .mjs
extension are packaged as modules and can be
used with a JavaScript import
statement or a <script type=module>
tag..js
extension are packaged to be used with a regular
<script>
tag (no type=module
). This format is called IIFE and declares a
MathLive
global variable from which the MathLive API can be accessed.require()
API. This was implemented in Node, but
also supported by some toolchains, such as WebPack. Unfortunately, some of
those older toolchains are still in use and difficult to move away from. In
order to support require()
the library needs to be packaged using the UMD
format. The UMD format is not supported by modern bundling tools, such as
esbuild
, which is what MathLive uses since 0.87.0. In this release, the
support for UMD is re-introduced by implementing it manually in MathLive,
rather than relying on the bundler.Changelog
0.89.0 2023-02-12
a(b)^2
was invalid.Changelog
0.87.1 2023-01-26
\operatorname{}
and \mathrm{}
/
after f(x)
will now consider f(x)
as the numerator,
instead of (x)
makeSharedVirtualKeyboard()
was incorrectly
specified as a private type.control
or command
key would
not reset the inline keystroke buffer. As a result, typing s
+ i
+
ctrl
-6
+ n
would yield \sin
instead of \si^n
.textarea
element. Only
dispatch an "input"
event with an inputType
of "insertLineBreak"
when
the user pressed the RETURN or ENTER key. Also dispatch a focusin
and focusout
event when applicable.Changelog
0.87.0 2023-01-20
jsdom
for server-side rendering.rollup
to esbuild
\smallint
command was erroneously displayed as an extensible
symbolChangelog
0.86.1 2023-01-18
renderMathInElement()
to no longer be rendered
correctly (the necessary stylesheet was erroneously removed).\enclose
command could not be displayed in
some cases if the z-index
of the expression they decorated had certain
values.