@pie-lib/math-input-mathlive 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/lib/__tests__/mathlive-instance.test.js +34 -1
- package/lib/__tests__/mathlive-instance.test.js.map +1 -1
- package/lib/keypad/index.js +41 -8
- package/lib/keypad/index.js.map +1 -1
- package/lib/mathlive-instance.js +94 -28
- package/lib/mathlive-instance.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/mathlive-instance.test.js +30 -1
- package/src/keypad/index.jsx +34 -5
- package/src/mathlive-instance.js +95 -23
package/README.md
CHANGED
|
@@ -72,13 +72,28 @@ widget do not port and need a redesign (`mf.getElementInfo()` exposes per-elemen
|
|
|
72
72
|
- **Bundle.** The editor is ~227KB gzip plus ~296KB of KaTeX fonts, so it is
|
|
73
73
|
loaded lazily via dynamic `import()`. Render-only consumers can use
|
|
74
74
|
`mathlive/ssr` (~111KB gzip) through `latexToMarkup`.
|
|
75
|
-
- **
|
|
76
|
-
no copied files, no CDN:
|
|
75
|
+
- **Stylesheets: import both, once, in the host app.**
|
|
77
76
|
|
|
78
77
|
```js
|
|
79
|
-
import 'mathlive/fonts.css';
|
|
78
|
+
import 'mathlive/fonts.css'; // KaTeX @font-face rules
|
|
79
|
+
import 'mathlive/static.css'; // REQUIRED for convertLatexToMarkup output
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
+
`static.css` is not optional. Keypad labels and `mf.Static` in display mode are
|
|
83
|
+
rendered with `convertLatexToMarkup`, whose output relies on
|
|
84
|
+
`ML__vlist` / `ML__strut` / `ML__base` / `ML__sqrt-sign` / `ML__pstrut` and on
|
|
85
|
+
`svg { position: absolute; width: 100% }`. Without the stylesheet, static math
|
|
86
|
+
renders misaligned and stretchy accents (`\overrightarrow`,
|
|
87
|
+
`\overleftrightarrow`, `\overarc`) expand without bound - a keypad button can
|
|
88
|
+
end up stretching across the viewport. The keypad defends against the worst of
|
|
89
|
+
this (`overflow: hidden` plus an svg rule on the label), but correct layout
|
|
90
|
+
still needs the real stylesheet.
|
|
91
|
+
|
|
92
|
+
Live `<math-field>` elements style themselves via shadow DOM and are unaffected.
|
|
93
|
+
|
|
94
|
+
On fonts specifically, `fonts.css` is the recommended route - no copied files,
|
|
95
|
+
no CDN:
|
|
96
|
+
|
|
82
97
|
The stylesheet's relative `url(fonts/*.woff2)` paths are resolved by your
|
|
83
98
|
bundler, so the fonts are emitted with the build and content-hashed. It also
|
|
84
99
|
sets `--ML__static-fonts`, which makes MathLive skip font fetching entirely.
|
|
@@ -77,10 +77,43 @@ describe('mathlive-instance', function () {
|
|
|
77
77
|
it('returns undefined without an element', function () {
|
|
78
78
|
expect(instance.applyStaticMath(null, 'x')).toBeUndefined();
|
|
79
79
|
});
|
|
80
|
-
it('returns undefined when MathLive has not loaded', function () {
|
|
80
|
+
it('defers (returns undefined) when MathLive has not loaded', function () {
|
|
81
81
|
var el = document.createElement('div');
|
|
82
82
|
expect(instance.applyStaticMath(el, 'x')).toBeUndefined();
|
|
83
83
|
});
|
|
84
|
+
it('renders synchronously once MathLive is available', function () {
|
|
85
|
+
var el = document.createElement('div');
|
|
86
|
+
instance.__setMathLiveForTest({
|
|
87
|
+
convertLatexToMarkup: function convertLatexToMarkup(l) {
|
|
88
|
+
return "<span>".concat(l, "</span>");
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
expect(instance.applyStaticMath(el, '\\pi')).toBe(el);
|
|
92
|
+
expect(el.innerHTML).toEqual('<span>\\pi</span>');
|
|
93
|
+
});
|
|
94
|
+
it('falls back to the element textContent when no latex is passed', function () {
|
|
95
|
+
var el = document.createElement('div');
|
|
96
|
+
el.textContent = '\\theta';
|
|
97
|
+
instance.__setMathLiveForTest({
|
|
98
|
+
convertLatexToMarkup: function convertLatexToMarkup(l) {
|
|
99
|
+
return "<i>".concat(l, "</i>");
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
instance.applyStaticMath(el);
|
|
103
|
+
expect(el.innerHTML).toEqual('<i>\\theta</i>');
|
|
104
|
+
});
|
|
105
|
+
it('bridges stored latex (newLine embed) before rendering', function () {
|
|
106
|
+
var el = document.createElement('div');
|
|
107
|
+
instance.__setMathLiveForTest({
|
|
108
|
+
convertLatexToMarkup: function convertLatexToMarkup(l) {
|
|
109
|
+
return l;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
instance.applyStaticMath(el, 'a\\embed{newLine}[]b');
|
|
113
|
+
|
|
114
|
+
// \embed{newLine}[] must become a multiline environment
|
|
115
|
+
expect(el.innerHTML).toContain('displaylines');
|
|
116
|
+
});
|
|
84
117
|
});
|
|
85
118
|
describe('configureFonts', function () {
|
|
86
119
|
// MathLive's default fontsDirectory is the relative './fonts/', which it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mathlive-instance.test.js","names":["describe","instance","beforeEach","jest","resetModules","require","__resetEmbeds","it","registerEmbed","htmlString","latex","expect","registeredEmbeds","toEqual","getMacros","answerBlock","newLine","somethingCustom","mathliveLatex","custom","Error","not","toThrow","undefined","macros","parallelogram","toBeDefined","longdiv","napprox","applyStaticMath","toBeUndefined","el","document","createElement","_typeof2","configureFonts","toBe","MathfieldElement","__setMathLiveForTest","fontsDirectory","concat","baseURI","replace","startsWith","toBeNull","latexToMarkup"],"sources":["../../src/__tests__/mathlive-instance.test.js"],"sourcesContent":["describe('mathlive-instance', () => {\n let instance;\n\n beforeEach(() => {\n jest.resetModules();\n // eslint-disable-next-line global-require\n instance = require('../mathlive-instance');\n instance.__resetEmbeds();\n });\n\n describe('registerEmbed', () => {\n it('registers a known embed and exposes it as a macro', () => {\n instance.registerEmbed('answerBlock', () => ({\n htmlString: '<div class=\"answerBlock\"></div>',\n latex: () => '\\\\embed{answerBlock}[]',\n }));\n\n expect(instance.registeredEmbeds()).toEqual(['answerBlock']);\n // The macro tags output with data-embed so CSS can target it, replacing\n // MathQuill's htmlString hook.\n expect(instance.getMacros().answerBlock).toEqual('\\\\htmlData{embed=answerBlock}{\\\\placeholder{}}');\n });\n\n it('registers newLine as a harmless macro (it is handled by latex-bridge)', () => {\n instance.registerEmbed('newLine', () => ({ latex: () => '\\\\embed{newLine}[]' }));\n\n expect(instance.getMacros().newLine).toEqual('\\\\htmlData{embed=newLine}{}');\n });\n\n it('falls back to a placeholder for an unknown embed', () => {\n instance.registerEmbed('somethingCustom', () => ({ htmlString: '<b>x</b>' }));\n\n expect(instance.getMacros().somethingCustom).toEqual('\\\\htmlData{embed=somethingCustom}{\\\\placeholder{}}');\n });\n\n it('honours an explicit mathliveLatex from the factory', () => {\n instance.registerEmbed('custom', () => ({ mathliveLatex: '\\\\alpha' }));\n\n expect(instance.getMacros().custom).toEqual('\\\\htmlData{embed=custom}{\\\\alpha}');\n });\n\n it('does not throw when the factory throws', () => {\n expect(() =>\n instance.registerEmbed('bad', () => {\n throw new Error('boom');\n }),\n ).not.toThrow();\n\n expect(instance.registeredEmbeds()).toEqual(['bad']);\n });\n\n it('ignores bad arguments', () => {\n instance.registerEmbed(undefined, () => ({}));\n instance.registerEmbed('noFactory', undefined);\n\n expect(instance.registeredEmbeds()).toEqual([]);\n });\n\n it('always includes the pie macro set', () => {\n const macros = instance.getMacros();\n\n expect(macros.parallelogram).toBeDefined();\n expect(macros.longdiv).toBeDefined();\n expect(macros.napprox).toEqual('\\\\not\\\\approx');\n });\n });\n\n describe('applyStaticMath', () => {\n it('returns undefined without an element', () => {\n expect(instance.applyStaticMath(null, 'x')).toBeUndefined();\n });\n\n it('returns undefined when MathLive has not loaded', () => {\n const el = document.createElement('div');\n\n expect(instance.applyStaticMath(el, 'x')).toBeUndefined();\n });\n });\n\n describe('configureFonts', () => {\n // MathLive's default fontsDirectory is the relative './fonts/', which it\n // resolves against its own (empty, when bundled) script url and throws\n // \"Invalid base URL\" from loadFonts. Paths must become absolute.\n it('is exported and callable before MathLive loads', () => {\n expect(typeof instance.configureFonts).toBe('function');\n expect(() => instance.configureFonts('/mathlive-fonts')).not.toThrow();\n });\n\n it('accepts null to disable font loading', () => {\n expect(() => instance.configureFonts(null)).not.toThrow();\n });\n\n it('applies an absolute url to an already-loaded MathfieldElement', () => {\n const MathfieldElement = {};\n\n // simulate a loaded instance\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('/mathlive-fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual(`${document.baseURI.replace(/\\/$/, '')}/mathlive-fonts`);\n expect(MathfieldElement.fontsDirectory.startsWith('http')).toBe(true);\n });\n\n it('leaves a fully-qualified url untouched', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('https://cdn.example.com/fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://cdn.example.com/fonts');\n });\n\n it('passes null through rather than resolving it', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts(null);\n\n expect(MathfieldElement.fontsDirectory).toBeNull();\n });\n });\n\n describe('latexToMarkup', () => {\n it('returns empty string when MathLive is not loaded', () => {\n expect(instance.latexToMarkup('\\\\pi')).toEqual('');\n });\n\n it('returns empty string for empty latex', () => {\n expect(instance.latexToMarkup('')).toEqual('');\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"mathlive-instance.test.js","names":["describe","instance","beforeEach","jest","resetModules","require","__resetEmbeds","it","registerEmbed","htmlString","latex","expect","registeredEmbeds","toEqual","getMacros","answerBlock","newLine","somethingCustom","mathliveLatex","custom","Error","not","toThrow","undefined","macros","parallelogram","toBeDefined","longdiv","napprox","applyStaticMath","toBeUndefined","el","document","createElement","__setMathLiveForTest","convertLatexToMarkup","l","concat","toBe","innerHTML","textContent","toContain","_typeof2","configureFonts","MathfieldElement","fontsDirectory","baseURI","replace","startsWith","toBeNull","latexToMarkup"],"sources":["../../src/__tests__/mathlive-instance.test.js"],"sourcesContent":["describe('mathlive-instance', () => {\n let instance;\n\n beforeEach(() => {\n jest.resetModules();\n // eslint-disable-next-line global-require\n instance = require('../mathlive-instance');\n instance.__resetEmbeds();\n });\n\n describe('registerEmbed', () => {\n it('registers a known embed and exposes it as a macro', () => {\n instance.registerEmbed('answerBlock', () => ({\n htmlString: '<div class=\"answerBlock\"></div>',\n latex: () => '\\\\embed{answerBlock}[]',\n }));\n\n expect(instance.registeredEmbeds()).toEqual(['answerBlock']);\n // The macro tags output with data-embed so CSS can target it, replacing\n // MathQuill's htmlString hook.\n expect(instance.getMacros().answerBlock).toEqual('\\\\htmlData{embed=answerBlock}{\\\\placeholder{}}');\n });\n\n it('registers newLine as a harmless macro (it is handled by latex-bridge)', () => {\n instance.registerEmbed('newLine', () => ({ latex: () => '\\\\embed{newLine}[]' }));\n\n expect(instance.getMacros().newLine).toEqual('\\\\htmlData{embed=newLine}{}');\n });\n\n it('falls back to a placeholder for an unknown embed', () => {\n instance.registerEmbed('somethingCustom', () => ({ htmlString: '<b>x</b>' }));\n\n expect(instance.getMacros().somethingCustom).toEqual('\\\\htmlData{embed=somethingCustom}{\\\\placeholder{}}');\n });\n\n it('honours an explicit mathliveLatex from the factory', () => {\n instance.registerEmbed('custom', () => ({ mathliveLatex: '\\\\alpha' }));\n\n expect(instance.getMacros().custom).toEqual('\\\\htmlData{embed=custom}{\\\\alpha}');\n });\n\n it('does not throw when the factory throws', () => {\n expect(() =>\n instance.registerEmbed('bad', () => {\n throw new Error('boom');\n }),\n ).not.toThrow();\n\n expect(instance.registeredEmbeds()).toEqual(['bad']);\n });\n\n it('ignores bad arguments', () => {\n instance.registerEmbed(undefined, () => ({}));\n instance.registerEmbed('noFactory', undefined);\n\n expect(instance.registeredEmbeds()).toEqual([]);\n });\n\n it('always includes the pie macro set', () => {\n const macros = instance.getMacros();\n\n expect(macros.parallelogram).toBeDefined();\n expect(macros.longdiv).toBeDefined();\n expect(macros.napprox).toEqual('\\\\not\\\\approx');\n });\n });\n\n describe('applyStaticMath', () => {\n it('returns undefined without an element', () => {\n expect(instance.applyStaticMath(null, 'x')).toBeUndefined();\n });\n\n it('defers (returns undefined) when MathLive has not loaded', () => {\n const el = document.createElement('div');\n\n expect(instance.applyStaticMath(el, 'x')).toBeUndefined();\n });\n\n it('renders synchronously once MathLive is available', () => {\n const el = document.createElement('div');\n\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<span>${l}</span>` });\n\n expect(instance.applyStaticMath(el, '\\\\pi')).toBe(el);\n expect(el.innerHTML).toEqual('<span>\\\\pi</span>');\n });\n\n it('falls back to the element textContent when no latex is passed', () => {\n const el = document.createElement('div');\n\n el.textContent = '\\\\theta';\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<i>${l}</i>` });\n instance.applyStaticMath(el);\n\n expect(el.innerHTML).toEqual('<i>\\\\theta</i>');\n });\n\n it('bridges stored latex (newLine embed) before rendering', () => {\n const el = document.createElement('div');\n\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => l });\n instance.applyStaticMath(el, 'a\\\\embed{newLine}[]b');\n\n // \\embed{newLine}[] must become a multiline environment\n expect(el.innerHTML).toContain('displaylines');\n });\n });\n\n describe('configureFonts', () => {\n // MathLive's default fontsDirectory is the relative './fonts/', which it\n // resolves against its own (empty, when bundled) script url and throws\n // \"Invalid base URL\" from loadFonts. Paths must become absolute.\n it('is exported and callable before MathLive loads', () => {\n expect(typeof instance.configureFonts).toBe('function');\n expect(() => instance.configureFonts('/mathlive-fonts')).not.toThrow();\n });\n\n it('accepts null to disable font loading', () => {\n expect(() => instance.configureFonts(null)).not.toThrow();\n });\n\n it('applies an absolute url to an already-loaded MathfieldElement', () => {\n const MathfieldElement = {};\n\n // simulate a loaded instance\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('/mathlive-fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual(`${document.baseURI.replace(/\\/$/, '')}/mathlive-fonts`);\n expect(MathfieldElement.fontsDirectory.startsWith('http')).toBe(true);\n });\n\n it('leaves a fully-qualified url untouched', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('https://cdn.example.com/fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://cdn.example.com/fonts');\n });\n\n it('passes null through rather than resolving it', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts(null);\n\n expect(MathfieldElement.fontsDirectory).toBeNull();\n });\n });\n\n describe('latexToMarkup', () => {\n it('returns empty string when MathLive is not loaded', () => {\n expect(instance.latexToMarkup('\\\\pi')).toEqual('');\n });\n\n it('returns empty string for empty latex', () => {\n expect(instance.latexToMarkup('')).toEqual('');\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
package/lib/keypad/index.js
CHANGED
|
@@ -53,6 +53,18 @@ var LabelHolder = (0, _styles.styled)('span')(function () {
|
|
|
53
53
|
alignItems: 'center',
|
|
54
54
|
justifyContent: 'center',
|
|
55
55
|
lineHeight: 1,
|
|
56
|
+
// Never let a label size its grid column. Stretchy accents
|
|
57
|
+
// (\overrightarrow, \overleftrightarrow, \overarc) render an <svg> that
|
|
58
|
+
// mathlive-static.css positions absolutely at width:100%; if that stylesheet
|
|
59
|
+
// is missing the svg lays out statically and expands without bound, dragging
|
|
60
|
+
// the whole column across the screen. `overflow: hidden` also collapses the
|
|
61
|
+
// label's min-content contribution, so the grid can't blow out either way.
|
|
62
|
+
maxWidth: '100%',
|
|
63
|
+
overflow: 'hidden',
|
|
64
|
+
'& svg': {
|
|
65
|
+
position: 'absolute',
|
|
66
|
+
width: '100%'
|
|
67
|
+
},
|
|
56
68
|
// Answer-block / empty-slot boxes inside a label.
|
|
57
69
|
'& .ML__placeholder': {
|
|
58
70
|
backgroundColor: _renderUi.color.keypadEmptyPlaceholder ? _renderUi.color.keypadEmptyPlaceholder() : undefined
|
|
@@ -74,22 +86,43 @@ var LatexLabel = exports.LatexLabel = /*#__PURE__*/function (_React$Component) {
|
|
|
74
86
|
key: "componentDidMount",
|
|
75
87
|
value: function () {
|
|
76
88
|
var _componentDidMount = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
|
|
89
|
+
var markup;
|
|
77
90
|
return _regenerator["default"].wrap(function (_context) {
|
|
78
91
|
while (1) switch (_context.prev = _context.next) {
|
|
79
92
|
case 0:
|
|
80
|
-
if (this.state.markup) {
|
|
81
|
-
_context.next =
|
|
93
|
+
if (!this.state.markup) {
|
|
94
|
+
_context.next = 1;
|
|
82
95
|
break;
|
|
83
96
|
}
|
|
84
|
-
_context.
|
|
85
|
-
return (0, _mathliveInstance.loadMathLive)();
|
|
97
|
+
return _context.abrupt("return");
|
|
86
98
|
case 1:
|
|
99
|
+
_context.next = 2;
|
|
100
|
+
return (0, _mathliveInstance.loadMathLive)();
|
|
101
|
+
case 2:
|
|
87
102
|
if (!this.unmounted) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
103
|
+
_context.next = 3;
|
|
104
|
+
break;
|
|
91
105
|
}
|
|
92
|
-
|
|
106
|
+
return _context.abrupt("return");
|
|
107
|
+
case 3:
|
|
108
|
+
markup = (0, _mathliveInstance.latexToMarkup)(this.props.latex);
|
|
109
|
+
if (!markup) {
|
|
110
|
+
_context.next = 4;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
this.setState({
|
|
114
|
+
markup: markup
|
|
115
|
+
});
|
|
116
|
+
return _context.abrupt("return");
|
|
117
|
+
case 4:
|
|
118
|
+
// Still nothing: the engine is genuinely unavailable (a missing chunk, a
|
|
119
|
+
// blocked request). Keep the raw-latex fallback visible rather than an
|
|
120
|
+
// empty button, and log once so this is diagnosable.
|
|
121
|
+
if (!LatexLabel.warned) {
|
|
122
|
+
LatexLabel.warned = true;
|
|
123
|
+
log('MathLive unavailable - keypad labels are falling back to raw latex');
|
|
124
|
+
}
|
|
125
|
+
case 5:
|
|
93
126
|
case "end":
|
|
94
127
|
return _context.stop();
|
|
95
128
|
}
|
package/lib/keypad/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_propTypes","_Button","_IconButton","_styles","_debug","_lodashEs","_renderUi","_keys","_keysLayout","_commonStyles","_mathliveInstance","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_callSuper","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","Boolean","prototype","valueOf","call","log","debug","LabelHolder","styled","pointerEvents","textTransform","color","text","display","alignItems","justifyContent","lineHeight","backgroundColor","keypadEmptyPlaceholder","undefined","LatexLabel","exports","_React$Component","props","_this","_classCallCheck2","state","markup","latexToMarkup","latex","_inherits2","_createClass2","key","value","_componentDidMount","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","loadMathLive","unmounted","setState","stop","componentDidMount","componentDidUpdate","prevProps","componentWillUnmount","render","createElement","dangerouslySetInnerHTML","__html","React","Component","PropTypes","string","isRequired","createCustomLayout","layoutObj","gridTemplateColumns","concat","columns","gridTemplateRows","rows","gridAutoFlow","KeyPadContainer","commonKeyboardStyles","width","gridRowGap","gridColumnGap","fontFamily","buttonBackground","category","keypadButtonOperator","keypadButton","keypadButtonOperatorHover","keypadButtonHover","StyledButton","Button","_ref","isDelete","isComma","isDot","minWidth","fontSize","borderRadius","StyledLatexButtonWrapper","_ref2","padding","margin","StyledIconButton","IconButton","_ref3","height","KeyPad","_React$Component2","_this2","setKeypadInteraction","onPress","base","extras","flatten","_toConsumableArray2","sortKeys","noDecimal","write","label","keypadRef","createRef","_this$keypadRef","keyPadElement","current","mainContainer","closest","currentToolbar","controlledKeypadMode","mainContainerPosition","getBoundingClientRect","currentToolbarPosition","difference","top","totalHeight","style","addEventListener","handleKeypadInteraction","_this$keypadRef2","removeEventListener","_this3","_this$props","className","baseSet","additionalKeys","layoutForKeyPad","onFocus","mode","noBaseSet","keysWithoutBaseSet","includes","allKeys","flowKeys","shift","Math","floor","ref","join","map","k","index","command","extra","actions","extraProps","onClick","buttonClick","bind","disabled","keyIsNotAllowed","ariaLabel","name","_extends2","Icon","icon","tabIndex","size","bool","array","object","func","oneOfType","number","_default"],"sources":["../../src/keypad/index.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport { styled } from '@mui/material/styles';\nimport debug from 'debug';\nimport { flatten } from 'lodash-es';\nimport { color } from '@pie-lib/render-ui';\n\nimport { baseSet } from '../keys';\nimport { sortKeys } from './keys-layout';\nimport { commonKeyboardStyles } from '../mf/common-styles';\nimport { loadMathLive, latexToMarkup } from '../mathlive-instance';\n\nconst log = debug('pie-lib:math-input-mathlive:keypad');\n\n/**\n * A LaTeX keypad label.\n *\n * The MathQuill implementation rendered every LaTeX label as its own\n * `MQ.StaticMath` instance. Here each label is static HTML produced once by\n * `convertLatexToMarkup`, so a 40-key keypad no longer creates 40 live math\n * instances.\n */\n// The `color.*()` helpers must be called lazily, inside the styled callback.\n// Evaluating them in a plain object literal runs them at module load, which\n// breaks any consumer that mocks a subset of @pie-lib/render-ui.\nconst LabelHolder = styled('span')(() => ({\n pointerEvents: 'none',\n textTransform: 'none',\n color: color.text(),\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 1,\n // Answer-block / empty-slot boxes inside a label.\n '& .ML__placeholder': {\n backgroundColor: color.keypadEmptyPlaceholder ? color.keypadEmptyPlaceholder() : undefined,\n },\n}));\n\nexport class LatexLabel extends React.Component {\n static propTypes = {\n latex: PropTypes.string.isRequired,\n };\n\n constructor(props) {\n super(props);\n this.state = { markup: latexToMarkup(props.latex) };\n }\n\n async componentDidMount() {\n // MathLive may not have finished loading when the keypad first mounts.\n if (!this.state.markup) {\n await loadMathLive();\n\n if (!this.unmounted) {\n this.setState({ markup: latexToMarkup(this.props.latex) });\n }\n }\n }\n\n componentDidUpdate(prevProps) {\n if (prevProps.latex !== this.props.latex) {\n this.setState({ markup: latexToMarkup(this.props.latex) });\n }\n }\n\n componentWillUnmount() {\n this.unmounted = true;\n }\n\n render() {\n const { markup } = this.state;\n\n // Fall back to the raw latex so a button is never blank.\n return markup ? (\n // eslint-disable-next-line react/no-danger\n <LabelHolder dangerouslySetInnerHTML={{ __html: markup }} />\n ) : (\n <LabelHolder>{this.props.latex}</LabelHolder>\n );\n }\n}\n\nconst createCustomLayout = (layoutObj) => {\n if (layoutObj) {\n return {\n gridTemplateColumns: `repeat(${layoutObj.columns}, minmax(min-content, 150px))`,\n gridTemplateRows: `repeat(${layoutObj.rows}, minmax(40px, 60px))`,\n gridAutoFlow: 'initial',\n };\n }\n\n return {};\n};\n\nconst KeyPadContainer = styled('div')(() => ({\n ...commonKeyboardStyles,\n width: '100%',\n display: 'grid',\n gridTemplateRows: 'repeat(5, minmax(40px, 60px))',\n gridRowGap: '0px',\n gridColumnGap: '0px',\n gridAutoFlow: 'column',\n '&.character': {\n textTransform: 'initial !important',\n gridTemplateRows: 'repeat(5, minmax(40px, 50px)) !important',\n },\n '&.language': {\n gridTemplateRows: 'repeat(4, minmax(40px, 50px)) !important',\n '& *': {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n },\n },\n}));\n\nconst buttonBackground = (category) => ({\n backgroundColor: category === 'operators' ? color.keypadButtonOperator() : color.keypadButton(),\n '&:hover': {\n backgroundColor: category === 'operators' ? color.keypadButtonOperatorHover() : color.keypadButtonHover(),\n },\n});\n\nconst StyledButton = styled(Button)(({ category, isDelete, isComma, isDot }) => ({\n minWidth: 'auto',\n textTransform: 'none',\n fontSize: isComma || isDot ? '200% !important' : '140% !important',\n lineHeight: isComma || isDot ? '100%' : 'normal',\n color: color.text(),\n ...buttonBackground(category),\n borderRadius: 0,\n ...(isDelete && {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n }),\n}));\n\nconst StyledLatexButtonWrapper = styled(Button)(({ category }) => ({\n textTransform: 'none',\n padding: 0,\n margin: 0,\n fontSize: '110% !important',\n minWidth: 'auto',\n borderRadius: 0,\n ...buttonBackground(category),\n}));\n\nconst StyledIconButton = styled(IconButton)(({ category }) => ({\n minWidth: 'auto',\n ...buttonBackground(category),\n borderRadius: 0,\n '& .icon': {\n height: '30px',\n },\n}));\n\nexport class KeyPad extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n controlledKeypadMode: PropTypes.bool,\n baseSet: PropTypes.array,\n additionalKeys: PropTypes.array,\n layoutForKeyPad: PropTypes.object,\n onPress: PropTypes.func.isRequired,\n onFocus: PropTypes.func,\n noDecimal: PropTypes.bool,\n setKeypadInteraction: PropTypes.func,\n mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n };\n\n static defaultProps = {\n baseSet: baseSet,\n noDecimal: false,\n };\n\n constructor(props) {\n super(props);\n this.keypadRef = React.createRef();\n }\n\n componentDidMount() {\n // Ensure MathLive is available for the LaTeX labels.\n loadMathLive();\n\n const keyPadElement = this.keypadRef?.current;\n const mainContainer = keyPadElement?.closest('.main-container');\n const currentToolbar = keyPadElement?.closest('.pie-toolbar');\n\n // need only for math keyboard so we need also controlledKeypadMode\n if (this.props.controlledKeypadMode && mainContainer && currentToolbar) {\n const mainContainerPosition = mainContainer.getBoundingClientRect();\n const currentToolbarPosition = currentToolbar.getBoundingClientRect();\n const difference =\n mainContainerPosition.top +\n mainContainerPosition.height -\n (currentToolbarPosition.top + currentToolbarPosition.height);\n\n if (difference < 0) {\n const totalHeight = mainContainerPosition.height + mainContainerPosition.top - difference;\n\n mainContainer.style.height = `${totalHeight}px`;\n }\n }\n\n if (keyPadElement) {\n keyPadElement.addEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.addEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n componentWillUnmount() {\n const keyPadElement = this.keypadRef?.current;\n\n if (this.props.controlledKeypadMode && keyPadElement) {\n const mainContainer = keyPadElement.closest('.main-container');\n\n if (mainContainer) {\n mainContainer.style.height = 'unset';\n }\n }\n\n if (keyPadElement) {\n keyPadElement.removeEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.removeEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n handleKeypadInteraction = () => {\n if (this.props.setKeypadInteraction) {\n this.props.setKeypadInteraction(true);\n }\n };\n\n buttonClick = (key) => {\n log('[buttonClick]', key);\n this.props.onPress(key);\n };\n\n flowKeys = (base, extras) => flatten([...sortKeys(base), ...sortKeys(extras)]);\n\n keyIsNotAllowed = (key) => {\n const { noDecimal } = this.props;\n\n return !!(((key.write === '.' && key.label === '.') || (key.write === ',' && key.label === ',')) && noDecimal);\n };\n\n render() {\n const { className, baseSet: base, additionalKeys, layoutForKeyPad, onFocus, mode } = this.props;\n\n const noBaseSet = ['non-negative-integers', 'integers', 'decimals', 'fractions', 'item-authoring', 'language'];\n const keysWithoutBaseSet = noBaseSet.includes(mode);\n const allKeys = keysWithoutBaseSet\n ? this.flowKeys([], additionalKeys || [])\n : this.flowKeys(base, additionalKeys || []);\n\n const shift = allKeys.length % 5 ? 1 : 0;\n const style = {\n gridTemplateColumns: `repeat(${Math.floor(allKeys.length / 5) + shift}, minmax(min-content, 150px))`,\n ...createCustomLayout(layoutForKeyPad),\n };\n\n return (\n <KeyPadContainer\n ref={this.keypadRef}\n className={[className, mode].filter(Boolean).join(' ')}\n style={style}\n onFocus={onFocus}\n >\n {allKeys.map((k, index) => {\n if (!k) {\n return <span key={`empty-${index}`} />;\n }\n\n const key = `${k.label || k.latex || k.command}-${index}`;\n const category = !keysWithoutBaseSet ? k.category : undefined;\n const extra = { ...(k.actions || {}), ...(k.extraProps || {}) };\n const onClick = this.buttonClick.bind(this, k);\n const disabled = this.keyIsNotAllowed(k);\n const ariaLabel = k.ariaLabel ? k.ariaLabel : k.name || k.label;\n\n if (k.latex) {\n return (\n <StyledLatexButtonWrapper\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n aria-label={ariaLabel}\n {...extra}\n >\n <LatexLabel latex={k.latex} />\n </StyledLatexButtonWrapper>\n );\n }\n\n if (k.label) {\n return (\n <StyledButton\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n isDelete={k.label === '⌫'}\n isComma={k.label === ','}\n isDot={k.label === '.'}\n aria-label={ariaLabel}\n {...extra}\n >\n {k.label}\n </StyledButton>\n );\n }\n\n const Icon = k.icon ? k.icon : 'div';\n\n return (\n <StyledIconButton\n key={key}\n tabIndex={'-1'}\n onClick={onClick}\n disabled={disabled}\n category={category}\n size=\"large\"\n {...extra}\n >\n <Icon className=\"icon\" />\n </StyledIconButton>\n );\n })}\n </KeyPadContainer>\n );\n }\n}\n\nexport default KeyPad;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_propTypes","_Button","_IconButton","_styles","_debug","_lodashEs","_renderUi","_keys","_keysLayout","_commonStyles","_mathliveInstance","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_callSuper","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","Boolean","prototype","valueOf","call","log","debug","LabelHolder","styled","pointerEvents","textTransform","color","text","display","alignItems","justifyContent","lineHeight","maxWidth","overflow","position","width","backgroundColor","keypadEmptyPlaceholder","undefined","LatexLabel","exports","_React$Component","props","_this","_classCallCheck2","state","markup","latexToMarkup","latex","_inherits2","_createClass2","key","value","_componentDidMount","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","abrupt","loadMathLive","unmounted","setState","warned","stop","componentDidMount","componentDidUpdate","prevProps","componentWillUnmount","render","createElement","dangerouslySetInnerHTML","__html","React","Component","PropTypes","string","isRequired","createCustomLayout","layoutObj","gridTemplateColumns","concat","columns","gridTemplateRows","rows","gridAutoFlow","KeyPadContainer","commonKeyboardStyles","gridRowGap","gridColumnGap","fontFamily","buttonBackground","category","keypadButtonOperator","keypadButton","keypadButtonOperatorHover","keypadButtonHover","StyledButton","Button","_ref","isDelete","isComma","isDot","minWidth","fontSize","borderRadius","StyledLatexButtonWrapper","_ref2","padding","margin","StyledIconButton","IconButton","_ref3","height","KeyPad","_React$Component2","_this2","setKeypadInteraction","onPress","base","extras","flatten","_toConsumableArray2","sortKeys","noDecimal","write","label","keypadRef","createRef","_this$keypadRef","keyPadElement","current","mainContainer","closest","currentToolbar","controlledKeypadMode","mainContainerPosition","getBoundingClientRect","currentToolbarPosition","difference","top","totalHeight","style","addEventListener","handleKeypadInteraction","_this$keypadRef2","removeEventListener","_this3","_this$props","className","baseSet","additionalKeys","layoutForKeyPad","onFocus","mode","noBaseSet","keysWithoutBaseSet","includes","allKeys","flowKeys","shift","Math","floor","ref","join","map","k","index","command","extra","actions","extraProps","onClick","buttonClick","bind","disabled","keyIsNotAllowed","ariaLabel","name","_extends2","Icon","icon","tabIndex","size","bool","array","object","func","oneOfType","number","_default"],"sources":["../../src/keypad/index.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport { styled } from '@mui/material/styles';\nimport debug from 'debug';\nimport { flatten } from 'lodash-es';\nimport { color } from '@pie-lib/render-ui';\n\nimport { baseSet } from '../keys';\nimport { sortKeys } from './keys-layout';\nimport { commonKeyboardStyles } from '../mf/common-styles';\nimport { loadMathLive, latexToMarkup } from '../mathlive-instance';\n\nconst log = debug('pie-lib:math-input-mathlive:keypad');\n\n/**\n * A LaTeX keypad label.\n *\n * The MathQuill implementation rendered every LaTeX label as its own\n * `MQ.StaticMath` instance. Here each label is static HTML produced once by\n * `convertLatexToMarkup`, so a 40-key keypad no longer creates 40 live math\n * instances.\n */\n// The `color.*()` helpers must be called lazily, inside the styled callback.\n// Evaluating them in a plain object literal runs them at module load, which\n// breaks any consumer that mocks a subset of @pie-lib/render-ui.\nconst LabelHolder = styled('span')(() => ({\n pointerEvents: 'none',\n textTransform: 'none',\n color: color.text(),\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: 1,\n // Never let a label size its grid column. Stretchy accents\n // (\\overrightarrow, \\overleftrightarrow, \\overarc) render an <svg> that\n // mathlive-static.css positions absolutely at width:100%; if that stylesheet\n // is missing the svg lays out statically and expands without bound, dragging\n // the whole column across the screen. `overflow: hidden` also collapses the\n // label's min-content contribution, so the grid can't blow out either way.\n maxWidth: '100%',\n overflow: 'hidden',\n '& svg': {\n position: 'absolute',\n width: '100%',\n },\n // Answer-block / empty-slot boxes inside a label.\n '& .ML__placeholder': {\n backgroundColor: color.keypadEmptyPlaceholder ? color.keypadEmptyPlaceholder() : undefined,\n },\n}));\n\nexport class LatexLabel extends React.Component {\n static propTypes = {\n latex: PropTypes.string.isRequired,\n };\n\n constructor(props) {\n super(props);\n this.state = { markup: latexToMarkup(props.latex) };\n }\n\n async componentDidMount() {\n // MathLive may not have finished loading when the keypad first mounts.\n if (this.state.markup) {\n return;\n }\n\n await loadMathLive();\n\n if (this.unmounted) {\n return;\n }\n\n const markup = latexToMarkup(this.props.latex);\n\n if (markup) {\n this.setState({ markup });\n return;\n }\n\n // Still nothing: the engine is genuinely unavailable (a missing chunk, a\n // blocked request). Keep the raw-latex fallback visible rather than an\n // empty button, and log once so this is diagnosable.\n if (!LatexLabel.warned) {\n LatexLabel.warned = true;\n log('MathLive unavailable - keypad labels are falling back to raw latex');\n }\n }\n\n componentDidUpdate(prevProps) {\n if (prevProps.latex !== this.props.latex) {\n this.setState({ markup: latexToMarkup(this.props.latex) });\n }\n }\n\n componentWillUnmount() {\n this.unmounted = true;\n }\n\n render() {\n const { markup } = this.state;\n\n // Fall back to the raw latex so a button is never blank.\n return markup ? (\n // eslint-disable-next-line react/no-danger\n <LabelHolder dangerouslySetInnerHTML={{ __html: markup }} />\n ) : (\n <LabelHolder>{this.props.latex}</LabelHolder>\n );\n }\n}\n\nconst createCustomLayout = (layoutObj) => {\n if (layoutObj) {\n return {\n gridTemplateColumns: `repeat(${layoutObj.columns}, minmax(min-content, 150px))`,\n gridTemplateRows: `repeat(${layoutObj.rows}, minmax(40px, 60px))`,\n gridAutoFlow: 'initial',\n };\n }\n\n return {};\n};\n\nconst KeyPadContainer = styled('div')(() => ({\n ...commonKeyboardStyles,\n width: '100%',\n display: 'grid',\n gridTemplateRows: 'repeat(5, minmax(40px, 60px))',\n gridRowGap: '0px',\n gridColumnGap: '0px',\n gridAutoFlow: 'column',\n '&.character': {\n textTransform: 'initial !important',\n gridTemplateRows: 'repeat(5, minmax(40px, 50px)) !important',\n },\n '&.language': {\n gridTemplateRows: 'repeat(4, minmax(40px, 50px)) !important',\n '& *': {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n },\n },\n}));\n\nconst buttonBackground = (category) => ({\n backgroundColor: category === 'operators' ? color.keypadButtonOperator() : color.keypadButton(),\n '&:hover': {\n backgroundColor: category === 'operators' ? color.keypadButtonOperatorHover() : color.keypadButtonHover(),\n },\n});\n\nconst StyledButton = styled(Button)(({ category, isDelete, isComma, isDot }) => ({\n minWidth: 'auto',\n textTransform: 'none',\n fontSize: isComma || isDot ? '200% !important' : '140% !important',\n lineHeight: isComma || isDot ? '100%' : 'normal',\n color: color.text(),\n ...buttonBackground(category),\n borderRadius: 0,\n ...(isDelete && {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n }),\n}));\n\nconst StyledLatexButtonWrapper = styled(Button)(({ category }) => ({\n textTransform: 'none',\n padding: 0,\n margin: 0,\n fontSize: '110% !important',\n minWidth: 'auto',\n borderRadius: 0,\n ...buttonBackground(category),\n}));\n\nconst StyledIconButton = styled(IconButton)(({ category }) => ({\n minWidth: 'auto',\n ...buttonBackground(category),\n borderRadius: 0,\n '& .icon': {\n height: '30px',\n },\n}));\n\nexport class KeyPad extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n controlledKeypadMode: PropTypes.bool,\n baseSet: PropTypes.array,\n additionalKeys: PropTypes.array,\n layoutForKeyPad: PropTypes.object,\n onPress: PropTypes.func.isRequired,\n onFocus: PropTypes.func,\n noDecimal: PropTypes.bool,\n setKeypadInteraction: PropTypes.func,\n mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n };\n\n static defaultProps = {\n baseSet: baseSet,\n noDecimal: false,\n };\n\n constructor(props) {\n super(props);\n this.keypadRef = React.createRef();\n }\n\n componentDidMount() {\n // Ensure MathLive is available for the LaTeX labels.\n loadMathLive();\n\n const keyPadElement = this.keypadRef?.current;\n const mainContainer = keyPadElement?.closest('.main-container');\n const currentToolbar = keyPadElement?.closest('.pie-toolbar');\n\n // need only for math keyboard so we need also controlledKeypadMode\n if (this.props.controlledKeypadMode && mainContainer && currentToolbar) {\n const mainContainerPosition = mainContainer.getBoundingClientRect();\n const currentToolbarPosition = currentToolbar.getBoundingClientRect();\n const difference =\n mainContainerPosition.top +\n mainContainerPosition.height -\n (currentToolbarPosition.top + currentToolbarPosition.height);\n\n if (difference < 0) {\n const totalHeight = mainContainerPosition.height + mainContainerPosition.top - difference;\n\n mainContainer.style.height = `${totalHeight}px`;\n }\n }\n\n if (keyPadElement) {\n keyPadElement.addEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.addEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n componentWillUnmount() {\n const keyPadElement = this.keypadRef?.current;\n\n if (this.props.controlledKeypadMode && keyPadElement) {\n const mainContainer = keyPadElement.closest('.main-container');\n\n if (mainContainer) {\n mainContainer.style.height = 'unset';\n }\n }\n\n if (keyPadElement) {\n keyPadElement.removeEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.removeEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n handleKeypadInteraction = () => {\n if (this.props.setKeypadInteraction) {\n this.props.setKeypadInteraction(true);\n }\n };\n\n buttonClick = (key) => {\n log('[buttonClick]', key);\n this.props.onPress(key);\n };\n\n flowKeys = (base, extras) => flatten([...sortKeys(base), ...sortKeys(extras)]);\n\n keyIsNotAllowed = (key) => {\n const { noDecimal } = this.props;\n\n return !!(((key.write === '.' && key.label === '.') || (key.write === ',' && key.label === ',')) && noDecimal);\n };\n\n render() {\n const { className, baseSet: base, additionalKeys, layoutForKeyPad, onFocus, mode } = this.props;\n\n const noBaseSet = ['non-negative-integers', 'integers', 'decimals', 'fractions', 'item-authoring', 'language'];\n const keysWithoutBaseSet = noBaseSet.includes(mode);\n const allKeys = keysWithoutBaseSet\n ? this.flowKeys([], additionalKeys || [])\n : this.flowKeys(base, additionalKeys || []);\n\n const shift = allKeys.length % 5 ? 1 : 0;\n const style = {\n gridTemplateColumns: `repeat(${Math.floor(allKeys.length / 5) + shift}, minmax(min-content, 150px))`,\n ...createCustomLayout(layoutForKeyPad),\n };\n\n return (\n <KeyPadContainer\n ref={this.keypadRef}\n className={[className, mode].filter(Boolean).join(' ')}\n style={style}\n onFocus={onFocus}\n >\n {allKeys.map((k, index) => {\n if (!k) {\n return <span key={`empty-${index}`} />;\n }\n\n const key = `${k.label || k.latex || k.command}-${index}`;\n const category = !keysWithoutBaseSet ? k.category : undefined;\n const extra = { ...(k.actions || {}), ...(k.extraProps || {}) };\n const onClick = this.buttonClick.bind(this, k);\n const disabled = this.keyIsNotAllowed(k);\n const ariaLabel = k.ariaLabel ? k.ariaLabel : k.name || k.label;\n\n if (k.latex) {\n return (\n <StyledLatexButtonWrapper\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n aria-label={ariaLabel}\n {...extra}\n >\n <LatexLabel latex={k.latex} />\n </StyledLatexButtonWrapper>\n );\n }\n\n if (k.label) {\n return (\n <StyledButton\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n isDelete={k.label === '⌫'}\n isComma={k.label === ','}\n isDot={k.label === '.'}\n aria-label={ariaLabel}\n {...extra}\n >\n {k.label}\n </StyledButton>\n );\n }\n\n const Icon = k.icon ? k.icon : 'div';\n\n return (\n <StyledIconButton\n key={key}\n tabIndex={'-1'}\n onClick={onClick}\n disabled={disabled}\n category={category}\n size=\"large\"\n {...extra}\n >\n <Icon className=\"icon\" />\n </StyledIconButton>\n );\n })}\n </KeyPadContainer>\n );\n }\n}\n\nexport default KeyPad;\n"],"mappings":"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","ignoreList":[]}
|
package/lib/mathlive-instance.js
CHANGED
|
@@ -15,7 +15,7 @@ exports.__setMathLiveForTest = exports.__resetEmbeds = exports.PIE_MACROS = void
|
|
|
15
15
|
exports.applyStaticMath = applyStaticMath;
|
|
16
16
|
exports.getMathLive = exports.getMacros = exports.configureFonts = void 0;
|
|
17
17
|
exports.latexToMarkup = latexToMarkup;
|
|
18
|
-
exports.loadMathLive = void 0;
|
|
18
|
+
exports.loadMathLiveSync = exports.loadMathLive = void 0;
|
|
19
19
|
exports.registerEmbed = registerEmbed;
|
|
20
20
|
exports.registeredEmbeds = void 0;
|
|
21
21
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
@@ -133,9 +133,54 @@ var KNOWN_EMBED_LATEX = {
|
|
|
133
133
|
newLine: '',
|
|
134
134
|
answerBlock: '\\placeholder{}'
|
|
135
135
|
};
|
|
136
|
+
var loadWarned = false;
|
|
137
|
+
|
|
138
|
+
/** Apply post-load configuration exactly once. */
|
|
139
|
+
var configureLoaded = function configureLoaded() {
|
|
140
|
+
// Always replace MathLive's relative `'./fonts/'` default: it throws
|
|
141
|
+
// "Invalid base URL" when bundled. Either point at the host app's copy or
|
|
142
|
+
// disable font loading, both of which are safe.
|
|
143
|
+
if (fontsDirectory === undefined) {
|
|
144
|
+
log('no fontsDirectory configured - MathLive will use fallback fonts. ' + 'Call configureFonts("/path/to/fonts") with a copy of node_modules/mathlive/fonts to enable them.');
|
|
145
|
+
}
|
|
146
|
+
mathlive.MathfieldElement.fontsDirectory = fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Load MathLive synchronously when the bundler allows it.
|
|
151
|
+
*
|
|
152
|
+
* `require` keeps MathLive inside the host's bundle. An `import()` would make
|
|
153
|
+
* webpack emit a separate chunk, and a deployment that does not serve that
|
|
154
|
+
* chunk fails with a 404 at runtime - leaving every mathfield and keypad label
|
|
155
|
+
* blank with no obvious cause. Being in the main bundle also makes the engine
|
|
156
|
+
* available on first render, so callers that run synchronously (applyStaticMath,
|
|
157
|
+
* keypad labels) work without a second pass.
|
|
158
|
+
*
|
|
159
|
+
* Returns undefined during SSR or if the module is genuinely unavailable.
|
|
160
|
+
*
|
|
161
|
+
* @returns {object|undefined}
|
|
162
|
+
*/
|
|
163
|
+
var loadMathLiveSync = exports.loadMathLiveSync = function loadMathLiveSync() {
|
|
164
|
+
if (typeof window === 'undefined') {
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
if (!mathlive) {
|
|
168
|
+
try {
|
|
169
|
+
// eslint-disable-next-line global-require
|
|
170
|
+
mathlive = require('mathlive');
|
|
171
|
+
configureLoaded();
|
|
172
|
+
} catch (e) {
|
|
173
|
+
log('synchronous MathLive load unavailable: %s', e && e.message);
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return mathlive;
|
|
178
|
+
};
|
|
136
179
|
|
|
137
180
|
/**
|
|
138
|
-
* Load MathLive.
|
|
181
|
+
* Load MathLive. Prefers the synchronous path; falls back to a dynamic import.
|
|
182
|
+
* Resolves to undefined during SSR.
|
|
183
|
+
*
|
|
139
184
|
* @returns {Promise<object|undefined>}
|
|
140
185
|
*/
|
|
141
186
|
var loadMathLive = exports.loadMathLive = /*#__PURE__*/function () {
|
|
@@ -150,42 +195,47 @@ var loadMathLive = exports.loadMathLive = /*#__PURE__*/function () {
|
|
|
150
195
|
}
|
|
151
196
|
return _context.abrupt("return", undefined);
|
|
152
197
|
case 1:
|
|
153
|
-
if (mathlive) {
|
|
154
|
-
_context.next =
|
|
198
|
+
if (!mathlive) {
|
|
199
|
+
_context.next = 2;
|
|
155
200
|
break;
|
|
156
201
|
}
|
|
157
|
-
_context.
|
|
158
|
-
|
|
202
|
+
return _context.abrupt("return", mathlive);
|
|
203
|
+
case 2:
|
|
204
|
+
if (!loadMathLiveSync()) {
|
|
205
|
+
_context.next = 3;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
return _context.abrupt("return", mathlive);
|
|
209
|
+
case 3:
|
|
210
|
+
_context.prev = 3;
|
|
211
|
+
_context.next = 4;
|
|
159
212
|
return Promise.resolve().then(function () {
|
|
160
213
|
return _interopRequireWildcard(require('mathlive'));
|
|
161
214
|
});
|
|
162
|
-
case
|
|
215
|
+
case 4:
|
|
163
216
|
mathlive = _context.sent;
|
|
164
|
-
|
|
217
|
+
configureLoaded();
|
|
218
|
+
_context.next = 6;
|
|
165
219
|
break;
|
|
166
|
-
case 4:
|
|
167
|
-
_context.prev = 4;
|
|
168
|
-
_t = _context["catch"](2);
|
|
169
|
-
// MathLive is browser-only and ships an ESM-conditional exports map, so
|
|
170
|
-
// the import can fail in test/SSR-ish runtimes. Fail soft: callers all
|
|
171
|
-
// handle a missing instance (static rendering falls back to raw latex).
|
|
172
|
-
log('MathLive could not be loaded: %s', _t && _t.message);
|
|
173
|
-
return _context.abrupt("return", undefined);
|
|
174
220
|
case 5:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
221
|
+
_context.prev = 5;
|
|
222
|
+
_t = _context["catch"](3);
|
|
223
|
+
// Surface this once: a silent failure here renders every field and keypad
|
|
224
|
+
// label blank, which is very hard to trace back to a module load.
|
|
225
|
+
// Skipped under test, where jsdom cannot load the browser build.
|
|
226
|
+
if (!loadWarned && process.env.NODE_ENV !== 'test') {
|
|
227
|
+
loadWarned = true;
|
|
228
|
+
// eslint-disable-next-line no-console
|
|
229
|
+
console.warn('[@pie-lib/math-input-mathlive] MathLive could not be loaded; math input will not render. ' + 'If this is a bundling issue, ensure "mathlive" is resolvable from the host bundle. Cause: ' + (_t && _t.message));
|
|
180
230
|
}
|
|
181
|
-
|
|
231
|
+
return _context.abrupt("return", undefined);
|
|
182
232
|
case 6:
|
|
183
233
|
return _context.abrupt("return", mathlive);
|
|
184
234
|
case 7:
|
|
185
235
|
case "end":
|
|
186
236
|
return _context.stop();
|
|
187
237
|
}
|
|
188
|
-
}, _callee, null, [[
|
|
238
|
+
}, _callee, null, [[3, 5]]);
|
|
189
239
|
}));
|
|
190
240
|
return function loadMathLive() {
|
|
191
241
|
return _ref.apply(this, arguments);
|
|
@@ -271,22 +321,36 @@ var __setMathLiveForTest = exports.__setMathLiveForTest = function __setMathLive
|
|
|
271
321
|
* Render static math into an element. API-compatible with
|
|
272
322
|
* @pie-lib/math-input's `applyStaticMath`.
|
|
273
323
|
*
|
|
324
|
+
* Callers written against MathQuill invoke this synchronously from lifecycle
|
|
325
|
+
* methods, where MathLive (a dynamic import) may not have loaded yet. Rather
|
|
326
|
+
* than silently rendering nothing, this kicks off the load and re-applies once
|
|
327
|
+
* the engine is ready, so the element fills in on the next tick.
|
|
328
|
+
*
|
|
274
329
|
* @param {HTMLElement} element
|
|
275
330
|
* @param {string} [latex] assigned to the element before rendering
|
|
276
331
|
* @param {object} [options] `{ macros }` overrides
|
|
277
|
-
* @returns {HTMLElement|undefined} the element,
|
|
332
|
+
* @returns {HTMLElement|undefined} the element, or undefined if deferred
|
|
278
333
|
*/
|
|
279
334
|
function applyStaticMath(element, latex) {
|
|
280
335
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
281
336
|
if (!element || typeof window === 'undefined') {
|
|
282
337
|
return undefined;
|
|
283
338
|
}
|
|
284
|
-
|
|
339
|
+
|
|
340
|
+
// Capture the source now: if we defer, the element's textContent may have
|
|
341
|
+
// been overwritten by the time MathLive is ready.
|
|
342
|
+
var source = latex === undefined || latex === null ? element.textContent : latex;
|
|
343
|
+
var ml = getMathLive() || loadMathLiveSync();
|
|
285
344
|
if (!ml) {
|
|
286
|
-
log('applyStaticMath called before MathLive loaded -
|
|
345
|
+
log('applyStaticMath called before MathLive loaded - deferring until it is ready');
|
|
346
|
+
loadMathLive().then(function (loaded) {
|
|
347
|
+
// The element may have been unmounted while loading.
|
|
348
|
+
if (loaded && element.isConnected !== false) {
|
|
349
|
+
applyStaticMath(element, source, options);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
287
352
|
return undefined;
|
|
288
353
|
}
|
|
289
|
-
var source = latex === undefined || latex === null ? element.textContent : latex;
|
|
290
354
|
element.innerHTML = ml.convertLatexToMarkup((0, _latexBridge.toMathLive)(source), {
|
|
291
355
|
macros: _objectSpread(_objectSpread({}, getMacros()), options.macros || {})
|
|
292
356
|
});
|
|
@@ -303,7 +367,9 @@ function applyStaticMath(element, latex) {
|
|
|
303
367
|
*/
|
|
304
368
|
function latexToMarkup(latex) {
|
|
305
369
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
306
|
-
|
|
370
|
+
// Try the synchronous load so the very first render can produce markup
|
|
371
|
+
// instead of falling back to raw latex.
|
|
372
|
+
var ml = getMathLive() || loadMathLiveSync();
|
|
307
373
|
if (!ml || !latex) {
|
|
308
374
|
return '';
|
|
309
375
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mathlive-instance.js","names":["_debug","_interopRequireDefault","require","_latexBridge","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_interopRequireWildcard","WeakMap","n","__esModule","i","f","__proto__","_typeof","has","get","set","_t2","hasOwnProperty","call","log","debug","mathlive","fontsDirectory","absoluteFontsDirectory","dir","test","URL","document","baseURI","href","message","configureFonts","exports","MathfieldElement","PIE_MACROS","parallelogram","overarc","napprox","nsim","ncong","nparallel","perpendicular","divide","degree","square","longdiv","abs","embeds","Map","KNOWN_EMBED_LATEX","newLine","answerBlock","loadMathLive","_ref","_asyncToGenerator2","_regenerator","mark","_callee","_t","wrap","_context","prev","next","window","abrupt","undefined","Promise","resolve","then","sent","stop","getMathLive","getMacros","out","_ref2","name","latex","concat","registerEmbed","factory","definition","prototype","mathliveLatex","registeredEmbeds","Array","from","__resetEmbeds","clear","__setMathLiveForTest","stub","applyStaticMath","element","options","ml","source","textContent","innerHTML","convertLatexToMarkup","toMathLive","macros","latexToMarkup"],"sources":["../src/mathlive-instance.js"],"sourcesContent":["import debug from 'debug';\nimport { NEWLINE_EMBED, toMathLive } from './latex-bridge';\n\nconst log = debug('pie-lib:math-input-mathlive:instance');\n\n/**\n * MathLive bootstrap + compatibility shims for @pie-lib/math-input's public API.\n *\n * MathLive is loaded lazily and only in the browser: the editor bundle is\n * ~227KB gzip and registers custom elements, so it must never run during SSR.\n */\n\nlet mathlive;\n\n/**\n * Where the KaTeX woff2 fonts are served from, as configured by the host app.\n * `undefined` means \"not configured\"; `null` means \"explicitly disabled\".\n */\nlet fontsDirectory;\n\n/**\n * Turn a fonts path into a fully-qualified URL.\n *\n * MathLive's default `fontsDirectory` is the relative `'./fonts/'`, which it\n * resolves against its own script URL. Under a bundler (webpack/Next) that\n * script URL is empty, so `new URL('./fonts/', '')` throws\n * \"Failed to construct 'URL': Invalid base URL\" from `loadFonts`.\n * Resolving against `document.baseURI` avoids that entirely and honours any\n * <base href> / asset prefix the host app uses.\n */\nconst absoluteFontsDirectory = (dir) => {\n if (!dir) {\n return dir;\n }\n\n // Already absolute (http://, https://, //cdn...) - MathLive handles these.\n if (/^(?:[a-z+]+:)?\\/\\//i.test(dir)) {\n return dir;\n }\n\n try {\n return new URL(dir, document.baseURI).href;\n } catch (e) {\n log('could not resolve fontsDirectory \"%s\": %s', dir, e && e.message);\n return null;\n }\n};\n\n/**\n * Tell the package where the MathLive fonts are served from.\n *\n * Call before `loadMathLive()`. Accepts an absolute URL, a root-relative path\n * (`/mathlive-fonts`) or a relative one; pass `null` to skip font loading and\n * fall back to system fonts.\n *\n * The fonts ship inside the `mathlive` package (`node_modules/mathlive/fonts`)\n * and must be copied into whatever the host app serves statically.\n *\n * @param {string|null} dir\n */\nexport const configureFonts = (dir) => {\n fontsDirectory = dir;\n\n if (mathlive) {\n mathlive.MathfieldElement.fontsDirectory = absoluteFontsDirectory(dir);\n }\n};\n\n/**\n * Custom macros for the pie-specific commands that the MathQuill fork\n * understood but stock LaTeX does not.\n *\n * Kept deliberately in sync with the MathJax macros in\n * @pie-lib/math-rendering (`render-math.js`) so the same latex renders the same\n * way in the editor and in the static renderer.\n */\nexport const PIE_MACROS = {\n parallelogram: '\\\\htmlData{pie-macro=parallelogram}{\\\\unicode{\"25B1}}',\n overarc: '\\\\overparen{#1}',\n napprox: '\\\\not\\\\approx',\n nsim: '\\\\not\\\\sim',\n ncong: '\\\\not\\\\cong',\n nparallel: '\\\\not\\\\parallel',\n perpendicular: '\\\\perp',\n divide: '\\\\div',\n degree: '^{\\\\circ}',\n square: '\\\\unicode{\"25A1}',\n longdiv: '\\\\htmlData{pie-macro=longdiv}{#1}',\n abs: '\\\\left|#1\\\\right|',\n};\n\n/**\n * Registry for `registerEmbed`.\n *\n * MathLive has no embed plugin system, so an embed is expressed as a macro that\n * expands to real LaTeX. `\\htmlData{embed=<name>}` tags the rendered output so\n * consumers can target it with CSS exactly as they targeted the old\n * `htmlString` markup.\n *\n * Known embeds map to native constructs:\n * - `newLine` -> structural, handled by latex-bridge (`\\displaylines` + `\\\\`)\n * - `answerBlock`-> `\\placeholder{}` (interactive, read via the prompts API)\n *\n * @type {Map<string, {factory: Function, latex: string}>}\n */\nconst embeds = new Map();\n\nconst KNOWN_EMBED_LATEX = {\n // newLine is structural: it is translated by latex-bridge before it ever\n // reaches MathLive, so the macro only needs to be harmless.\n newLine: '',\n answerBlock: '\\\\placeholder{}',\n};\n\n/**\n * Load MathLive. Resolves to undefined during SSR.\n * @returns {Promise<object|undefined>}\n */\nexport const loadMathLive = async () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (!mathlive) {\n try {\n mathlive = await import('mathlive');\n } catch (e) {\n // MathLive is browser-only and ships an ESM-conditional exports map, so\n // the import can fail in test/SSR-ish runtimes. Fail soft: callers all\n // handle a missing instance (static rendering falls back to raw latex).\n log('MathLive could not be loaded: %s', e && e.message);\n return undefined;\n }\n\n // Always replace MathLive's relative `'./fonts/'` default: it throws\n // \"Invalid base URL\" when bundled. Either point at the host app's copy or\n // disable font loading, both of which are safe.\n if (fontsDirectory === undefined) {\n log(\n 'no fontsDirectory configured - MathLive will use fallback fonts. ' +\n 'Call configureFonts(\"/path/to/fonts\") with a copy of node_modules/mathlive/fonts to enable them.',\n );\n }\n\n mathlive.MathfieldElement.fontsDirectory =\n fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);\n }\n\n return mathlive;\n};\n\n/**\n * Synchronous accessor for an already-loaded MathLive.\n * @returns {object|undefined}\n */\nexport const getMathLive = () => mathlive;\n\n/**\n * The macro dictionary to hand to a mathfield: pie macros plus anything\n * registered through `registerEmbed`.\n *\n * @returns {object}\n */\nexport const getMacros = () => {\n const out = { ...PIE_MACROS };\n\n embeds.forEach(({ latex }, name) => {\n out[name] = `\\\\htmlData{embed=${name}}{${latex}}`;\n });\n\n return out;\n};\n\n/**\n * Register an embed. API-compatible with @pie-lib/math-input's `registerEmbed`\n * so existing callers do not change.\n *\n * MathQuill's factory returns `{ htmlString, text, latex }`. Only the\n * declarative parts survive: `latex` round-trips through a macro and the\n * styling hook becomes a `data-embed` attribute. Arbitrary DOM injection via\n * `htmlString` has no MathLive equivalent and is ignored.\n *\n * @param {string} name\n * @param {Function} factory\n */\nexport function registerEmbed(name, factory) {\n if (!name || typeof factory !== 'function') {\n return;\n }\n\n let definition = {};\n\n try {\n definition = factory() || {};\n } catch (e) {\n log('embed factory threw for \"%s\": %s', name, e.message);\n }\n\n const latex = Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name)\n ? KNOWN_EMBED_LATEX[name]\n : definition.mathliveLatex || '\\\\placeholder{}';\n\n if (!Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name) && !definition.mathliveLatex) {\n // Unknown third-party embed: degrade instead of throwing. `htmlString`\n // cannot be reproduced, so it renders as an editable slot.\n log(\n 'embed \"%s\" is not natively supported by MathLive; rendering as a placeholder. ' +\n 'Provide `mathliveLatex` in the factory result to control this.',\n name,\n );\n }\n\n embeds.set(name, { factory, latex });\n}\n\n/**\n * Embeds registered so far. Exposed for tests/diagnostics.\n * @returns {string[]}\n */\nexport const registeredEmbeds = () => Array.from(embeds.keys());\n\n/** Reset the embed registry. Test helper. */\nexport const __resetEmbeds = () => embeds.clear();\n\n/** Inject a stub MathLive instance. Test helper. */\nexport const __setMathLiveForTest = (stub) => {\n mathlive = stub;\n};\n\n/**\n * Render static math into an element. API-compatible with\n * @pie-lib/math-input's `applyStaticMath`.\n *\n * @param {HTMLElement} element\n * @param {string} [latex] assigned to the element before rendering\n * @param {object} [options] `{ macros }` overrides\n * @returns {HTMLElement|undefined} the element, for parity with the old return\n */\nexport function applyStaticMath(element, latex, options = {}) {\n if (!element || typeof window === 'undefined') {\n return undefined;\n }\n\n const ml = getMathLive();\n\n if (!ml) {\n log('applyStaticMath called before MathLive loaded - call loadMathLive() first');\n return undefined;\n }\n\n const source = latex === undefined || latex === null ? element.textContent : latex;\n\n element.innerHTML = ml.convertLatexToMarkup(toMathLive(source), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n });\n\n return element;\n}\n\n/**\n * Convert latex to markup using the pie macro set. Used for keypad labels and\n * any read-only rendering that does not need a live mathfield.\n *\n * @param {string} latex\n * @param {object} [options]\n * @returns {string} HTML markup, or '' if MathLive is not loaded\n */\nexport function latexToMarkup(latex, options = {}) {\n const ml = getMathLive();\n\n if (!ml || !latex) {\n return '';\n }\n\n try {\n return ml.convertLatexToMarkup(toMathLive(latex), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n ...options,\n });\n } catch (e) {\n log('convertLatexToMarkup failed for \"%s\": %s', latex, e.message);\n return '';\n }\n}\n\nexport { NEWLINE_EMBED };\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"mathlive-instance.js","names":["_debug","_interopRequireDefault","require","_latexBridge","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_interopRequireWildcard","WeakMap","n","__esModule","i","f","__proto__","_typeof","has","get","set","_t2","hasOwnProperty","call","log","debug","mathlive","fontsDirectory","absoluteFontsDirectory","dir","test","URL","document","baseURI","href","message","configureFonts","exports","MathfieldElement","PIE_MACROS","parallelogram","overarc","napprox","nsim","ncong","nparallel","perpendicular","divide","degree","square","longdiv","abs","embeds","Map","KNOWN_EMBED_LATEX","newLine","answerBlock","loadWarned","configureLoaded","undefined","loadMathLiveSync","window","loadMathLive","_ref","_asyncToGenerator2","_regenerator","mark","_callee","_t","wrap","_context","prev","next","abrupt","Promise","resolve","then","sent","process","env","NODE_ENV","console","warn","stop","getMathLive","getMacros","out","_ref2","name","latex","concat","registerEmbed","factory","definition","prototype","mathliveLatex","registeredEmbeds","Array","from","__resetEmbeds","clear","__setMathLiveForTest","stub","applyStaticMath","element","options","source","textContent","ml","loaded","isConnected","innerHTML","convertLatexToMarkup","toMathLive","macros","latexToMarkup"],"sources":["../src/mathlive-instance.js"],"sourcesContent":["import debug from 'debug';\nimport { NEWLINE_EMBED, toMathLive } from './latex-bridge';\n\nconst log = debug('pie-lib:math-input-mathlive:instance');\n\n/**\n * MathLive bootstrap + compatibility shims for @pie-lib/math-input's public API.\n *\n * MathLive is loaded lazily and only in the browser: the editor bundle is\n * ~227KB gzip and registers custom elements, so it must never run during SSR.\n */\n\nlet mathlive;\n\n/**\n * Where the KaTeX woff2 fonts are served from, as configured by the host app.\n * `undefined` means \"not configured\"; `null` means \"explicitly disabled\".\n */\nlet fontsDirectory;\n\n/**\n * Turn a fonts path into a fully-qualified URL.\n *\n * MathLive's default `fontsDirectory` is the relative `'./fonts/'`, which it\n * resolves against its own script URL. Under a bundler (webpack/Next) that\n * script URL is empty, so `new URL('./fonts/', '')` throws\n * \"Failed to construct 'URL': Invalid base URL\" from `loadFonts`.\n * Resolving against `document.baseURI` avoids that entirely and honours any\n * <base href> / asset prefix the host app uses.\n */\nconst absoluteFontsDirectory = (dir) => {\n if (!dir) {\n return dir;\n }\n\n // Already absolute (http://, https://, //cdn...) - MathLive handles these.\n if (/^(?:[a-z+]+:)?\\/\\//i.test(dir)) {\n return dir;\n }\n\n try {\n return new URL(dir, document.baseURI).href;\n } catch (e) {\n log('could not resolve fontsDirectory \"%s\": %s', dir, e && e.message);\n return null;\n }\n};\n\n/**\n * Tell the package where the MathLive fonts are served from.\n *\n * Call before `loadMathLive()`. Accepts an absolute URL, a root-relative path\n * (`/mathlive-fonts`) or a relative one; pass `null` to skip font loading and\n * fall back to system fonts.\n *\n * The fonts ship inside the `mathlive` package (`node_modules/mathlive/fonts`)\n * and must be copied into whatever the host app serves statically.\n *\n * @param {string|null} dir\n */\nexport const configureFonts = (dir) => {\n fontsDirectory = dir;\n\n if (mathlive) {\n mathlive.MathfieldElement.fontsDirectory = absoluteFontsDirectory(dir);\n }\n};\n\n/**\n * Custom macros for the pie-specific commands that the MathQuill fork\n * understood but stock LaTeX does not.\n *\n * Kept deliberately in sync with the MathJax macros in\n * @pie-lib/math-rendering (`render-math.js`) so the same latex renders the same\n * way in the editor and in the static renderer.\n */\nexport const PIE_MACROS = {\n parallelogram: '\\\\htmlData{pie-macro=parallelogram}{\\\\unicode{\"25B1}}',\n overarc: '\\\\overparen{#1}',\n napprox: '\\\\not\\\\approx',\n nsim: '\\\\not\\\\sim',\n ncong: '\\\\not\\\\cong',\n nparallel: '\\\\not\\\\parallel',\n perpendicular: '\\\\perp',\n divide: '\\\\div',\n degree: '^{\\\\circ}',\n square: '\\\\unicode{\"25A1}',\n longdiv: '\\\\htmlData{pie-macro=longdiv}{#1}',\n abs: '\\\\left|#1\\\\right|',\n};\n\n/**\n * Registry for `registerEmbed`.\n *\n * MathLive has no embed plugin system, so an embed is expressed as a macro that\n * expands to real LaTeX. `\\htmlData{embed=<name>}` tags the rendered output so\n * consumers can target it with CSS exactly as they targeted the old\n * `htmlString` markup.\n *\n * Known embeds map to native constructs:\n * - `newLine` -> structural, handled by latex-bridge (`\\displaylines` + `\\\\`)\n * - `answerBlock`-> `\\placeholder{}` (interactive, read via the prompts API)\n *\n * @type {Map<string, {factory: Function, latex: string}>}\n */\nconst embeds = new Map();\n\nconst KNOWN_EMBED_LATEX = {\n // newLine is structural: it is translated by latex-bridge before it ever\n // reaches MathLive, so the macro only needs to be harmless.\n newLine: '',\n answerBlock: '\\\\placeholder{}',\n};\n\nlet loadWarned = false;\n\n/** Apply post-load configuration exactly once. */\nconst configureLoaded = () => {\n // Always replace MathLive's relative `'./fonts/'` default: it throws\n // \"Invalid base URL\" when bundled. Either point at the host app's copy or\n // disable font loading, both of which are safe.\n if (fontsDirectory === undefined) {\n log(\n 'no fontsDirectory configured - MathLive will use fallback fonts. ' +\n 'Call configureFonts(\"/path/to/fonts\") with a copy of node_modules/mathlive/fonts to enable them.',\n );\n }\n\n mathlive.MathfieldElement.fontsDirectory =\n fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);\n};\n\n/**\n * Load MathLive synchronously when the bundler allows it.\n *\n * `require` keeps MathLive inside the host's bundle. An `import()` would make\n * webpack emit a separate chunk, and a deployment that does not serve that\n * chunk fails with a 404 at runtime - leaving every mathfield and keypad label\n * blank with no obvious cause. Being in the main bundle also makes the engine\n * available on first render, so callers that run synchronously (applyStaticMath,\n * keypad labels) work without a second pass.\n *\n * Returns undefined during SSR or if the module is genuinely unavailable.\n *\n * @returns {object|undefined}\n */\nexport const loadMathLiveSync = () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (!mathlive) {\n try {\n // eslint-disable-next-line global-require\n mathlive = require('mathlive');\n configureLoaded();\n } catch (e) {\n log('synchronous MathLive load unavailable: %s', e && e.message);\n return undefined;\n }\n }\n\n return mathlive;\n};\n\n/**\n * Load MathLive. Prefers the synchronous path; falls back to a dynamic import.\n * Resolves to undefined during SSR.\n *\n * @returns {Promise<object|undefined>}\n */\nexport const loadMathLive = async () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (mathlive) {\n return mathlive;\n }\n\n if (loadMathLiveSync()) {\n return mathlive;\n }\n\n try {\n mathlive = await import('mathlive');\n configureLoaded();\n } catch (e) {\n // Surface this once: a silent failure here renders every field and keypad\n // label blank, which is very hard to trace back to a module load.\n // Skipped under test, where jsdom cannot load the browser build.\n if (!loadWarned && process.env.NODE_ENV !== 'test') {\n loadWarned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@pie-lib/math-input-mathlive] MathLive could not be loaded; math input will not render. ' +\n 'If this is a bundling issue, ensure \"mathlive\" is resolvable from the host bundle. Cause: ' +\n (e && e.message),\n );\n }\n\n return undefined;\n }\n\n return mathlive;\n};\n\n/**\n * Synchronous accessor for an already-loaded MathLive.\n * @returns {object|undefined}\n */\nexport const getMathLive = () => mathlive;\n\n/**\n * The macro dictionary to hand to a mathfield: pie macros plus anything\n * registered through `registerEmbed`.\n *\n * @returns {object}\n */\nexport const getMacros = () => {\n const out = { ...PIE_MACROS };\n\n embeds.forEach(({ latex }, name) => {\n out[name] = `\\\\htmlData{embed=${name}}{${latex}}`;\n });\n\n return out;\n};\n\n/**\n * Register an embed. API-compatible with @pie-lib/math-input's `registerEmbed`\n * so existing callers do not change.\n *\n * MathQuill's factory returns `{ htmlString, text, latex }`. Only the\n * declarative parts survive: `latex` round-trips through a macro and the\n * styling hook becomes a `data-embed` attribute. Arbitrary DOM injection via\n * `htmlString` has no MathLive equivalent and is ignored.\n *\n * @param {string} name\n * @param {Function} factory\n */\nexport function registerEmbed(name, factory) {\n if (!name || typeof factory !== 'function') {\n return;\n }\n\n let definition = {};\n\n try {\n definition = factory() || {};\n } catch (e) {\n log('embed factory threw for \"%s\": %s', name, e.message);\n }\n\n const latex = Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name)\n ? KNOWN_EMBED_LATEX[name]\n : definition.mathliveLatex || '\\\\placeholder{}';\n\n if (!Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name) && !definition.mathliveLatex) {\n // Unknown third-party embed: degrade instead of throwing. `htmlString`\n // cannot be reproduced, so it renders as an editable slot.\n log(\n 'embed \"%s\" is not natively supported by MathLive; rendering as a placeholder. ' +\n 'Provide `mathliveLatex` in the factory result to control this.',\n name,\n );\n }\n\n embeds.set(name, { factory, latex });\n}\n\n/**\n * Embeds registered so far. Exposed for tests/diagnostics.\n * @returns {string[]}\n */\nexport const registeredEmbeds = () => Array.from(embeds.keys());\n\n/** Reset the embed registry. Test helper. */\nexport const __resetEmbeds = () => embeds.clear();\n\n/** Inject a stub MathLive instance. Test helper. */\nexport const __setMathLiveForTest = (stub) => {\n mathlive = stub;\n};\n\n/**\n * Render static math into an element. API-compatible with\n * @pie-lib/math-input's `applyStaticMath`.\n *\n * Callers written against MathQuill invoke this synchronously from lifecycle\n * methods, where MathLive (a dynamic import) may not have loaded yet. Rather\n * than silently rendering nothing, this kicks off the load and re-applies once\n * the engine is ready, so the element fills in on the next tick.\n *\n * @param {HTMLElement} element\n * @param {string} [latex] assigned to the element before rendering\n * @param {object} [options] `{ macros }` overrides\n * @returns {HTMLElement|undefined} the element, or undefined if deferred\n */\nexport function applyStaticMath(element, latex, options = {}) {\n if (!element || typeof window === 'undefined') {\n return undefined;\n }\n\n // Capture the source now: if we defer, the element's textContent may have\n // been overwritten by the time MathLive is ready.\n const source = latex === undefined || latex === null ? element.textContent : latex;\n const ml = getMathLive() || loadMathLiveSync();\n\n if (!ml) {\n log('applyStaticMath called before MathLive loaded - deferring until it is ready');\n\n loadMathLive().then((loaded) => {\n // The element may have been unmounted while loading.\n if (loaded && element.isConnected !== false) {\n applyStaticMath(element, source, options);\n }\n });\n\n return undefined;\n }\n\n element.innerHTML = ml.convertLatexToMarkup(toMathLive(source), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n });\n\n return element;\n}\n\n/**\n * Convert latex to markup using the pie macro set. Used for keypad labels and\n * any read-only rendering that does not need a live mathfield.\n *\n * @param {string} latex\n * @param {object} [options]\n * @returns {string} HTML markup, or '' if MathLive is not loaded\n */\nexport function latexToMarkup(latex, options = {}) {\n // Try the synchronous load so the very first render can produce markup\n // instead of falling back to raw latex.\n const ml = getMathLive() || loadMathLiveSync();\n\n if (!ml || !latex) {\n return '';\n }\n\n try {\n return ml.convertLatexToMarkup(toMathLive(latex), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n ...options,\n });\n } catch (e) {\n log('convertLatexToMarkup failed for \"%s\": %s', latex, e.message);\n return '';\n }\n}\n\nexport { NEWLINE_EMBED };\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -70,11 +70,40 @@ describe('mathlive-instance', () => {
|
|
|
70
70
|
expect(instance.applyStaticMath(null, 'x')).toBeUndefined();
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
it('returns undefined when MathLive has not loaded', () => {
|
|
73
|
+
it('defers (returns undefined) when MathLive has not loaded', () => {
|
|
74
74
|
const el = document.createElement('div');
|
|
75
75
|
|
|
76
76
|
expect(instance.applyStaticMath(el, 'x')).toBeUndefined();
|
|
77
77
|
});
|
|
78
|
+
|
|
79
|
+
it('renders synchronously once MathLive is available', () => {
|
|
80
|
+
const el = document.createElement('div');
|
|
81
|
+
|
|
82
|
+
instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<span>${l}</span>` });
|
|
83
|
+
|
|
84
|
+
expect(instance.applyStaticMath(el, '\\pi')).toBe(el);
|
|
85
|
+
expect(el.innerHTML).toEqual('<span>\\pi</span>');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('falls back to the element textContent when no latex is passed', () => {
|
|
89
|
+
const el = document.createElement('div');
|
|
90
|
+
|
|
91
|
+
el.textContent = '\\theta';
|
|
92
|
+
instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<i>${l}</i>` });
|
|
93
|
+
instance.applyStaticMath(el);
|
|
94
|
+
|
|
95
|
+
expect(el.innerHTML).toEqual('<i>\\theta</i>');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('bridges stored latex (newLine embed) before rendering', () => {
|
|
99
|
+
const el = document.createElement('div');
|
|
100
|
+
|
|
101
|
+
instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => l });
|
|
102
|
+
instance.applyStaticMath(el, 'a\\embed{newLine}[]b');
|
|
103
|
+
|
|
104
|
+
// \embed{newLine}[] must become a multiline environment
|
|
105
|
+
expect(el.innerHTML).toContain('displaylines');
|
|
106
|
+
});
|
|
78
107
|
});
|
|
79
108
|
|
|
80
109
|
describe('configureFonts', () => {
|
package/src/keypad/index.jsx
CHANGED
|
@@ -33,6 +33,18 @@ const LabelHolder = styled('span')(() => ({
|
|
|
33
33
|
alignItems: 'center',
|
|
34
34
|
justifyContent: 'center',
|
|
35
35
|
lineHeight: 1,
|
|
36
|
+
// Never let a label size its grid column. Stretchy accents
|
|
37
|
+
// (\overrightarrow, \overleftrightarrow, \overarc) render an <svg> that
|
|
38
|
+
// mathlive-static.css positions absolutely at width:100%; if that stylesheet
|
|
39
|
+
// is missing the svg lays out statically and expands without bound, dragging
|
|
40
|
+
// the whole column across the screen. `overflow: hidden` also collapses the
|
|
41
|
+
// label's min-content contribution, so the grid can't blow out either way.
|
|
42
|
+
maxWidth: '100%',
|
|
43
|
+
overflow: 'hidden',
|
|
44
|
+
'& svg': {
|
|
45
|
+
position: 'absolute',
|
|
46
|
+
width: '100%',
|
|
47
|
+
},
|
|
36
48
|
// Answer-block / empty-slot boxes inside a label.
|
|
37
49
|
'& .ML__placeholder': {
|
|
38
50
|
backgroundColor: color.keypadEmptyPlaceholder ? color.keypadEmptyPlaceholder() : undefined,
|
|
@@ -51,12 +63,29 @@ export class LatexLabel extends React.Component {
|
|
|
51
63
|
|
|
52
64
|
async componentDidMount() {
|
|
53
65
|
// MathLive may not have finished loading when the keypad first mounts.
|
|
54
|
-
if (
|
|
55
|
-
|
|
66
|
+
if (this.state.markup) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
56
69
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
await loadMathLive();
|
|
71
|
+
|
|
72
|
+
if (this.unmounted) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const markup = latexToMarkup(this.props.latex);
|
|
77
|
+
|
|
78
|
+
if (markup) {
|
|
79
|
+
this.setState({ markup });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Still nothing: the engine is genuinely unavailable (a missing chunk, a
|
|
84
|
+
// blocked request). Keep the raw-latex fallback visible rather than an
|
|
85
|
+
// empty button, and log once so this is diagnosable.
|
|
86
|
+
if (!LatexLabel.warned) {
|
|
87
|
+
LatexLabel.warned = true;
|
|
88
|
+
log('MathLive unavailable - keypad labels are falling back to raw latex');
|
|
60
89
|
}
|
|
61
90
|
}
|
|
62
91
|
|
package/src/mathlive-instance.js
CHANGED
|
@@ -112,38 +112,94 @@ const KNOWN_EMBED_LATEX = {
|
|
|
112
112
|
answerBlock: '\\placeholder{}',
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
+
let loadWarned = false;
|
|
116
|
+
|
|
117
|
+
/** Apply post-load configuration exactly once. */
|
|
118
|
+
const configureLoaded = () => {
|
|
119
|
+
// Always replace MathLive's relative `'./fonts/'` default: it throws
|
|
120
|
+
// "Invalid base URL" when bundled. Either point at the host app's copy or
|
|
121
|
+
// disable font loading, both of which are safe.
|
|
122
|
+
if (fontsDirectory === undefined) {
|
|
123
|
+
log(
|
|
124
|
+
'no fontsDirectory configured - MathLive will use fallback fonts. ' +
|
|
125
|
+
'Call configureFonts("/path/to/fonts") with a copy of node_modules/mathlive/fonts to enable them.',
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
mathlive.MathfieldElement.fontsDirectory =
|
|
130
|
+
fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);
|
|
131
|
+
};
|
|
132
|
+
|
|
115
133
|
/**
|
|
116
|
-
* Load MathLive
|
|
117
|
-
*
|
|
134
|
+
* Load MathLive synchronously when the bundler allows it.
|
|
135
|
+
*
|
|
136
|
+
* `require` keeps MathLive inside the host's bundle. An `import()` would make
|
|
137
|
+
* webpack emit a separate chunk, and a deployment that does not serve that
|
|
138
|
+
* chunk fails with a 404 at runtime - leaving every mathfield and keypad label
|
|
139
|
+
* blank with no obvious cause. Being in the main bundle also makes the engine
|
|
140
|
+
* available on first render, so callers that run synchronously (applyStaticMath,
|
|
141
|
+
* keypad labels) work without a second pass.
|
|
142
|
+
*
|
|
143
|
+
* Returns undefined during SSR or if the module is genuinely unavailable.
|
|
144
|
+
*
|
|
145
|
+
* @returns {object|undefined}
|
|
118
146
|
*/
|
|
119
|
-
export const
|
|
147
|
+
export const loadMathLiveSync = () => {
|
|
120
148
|
if (typeof window === 'undefined') {
|
|
121
149
|
return undefined;
|
|
122
150
|
}
|
|
123
151
|
|
|
124
152
|
if (!mathlive) {
|
|
125
153
|
try {
|
|
126
|
-
|
|
154
|
+
// eslint-disable-next-line global-require
|
|
155
|
+
mathlive = require('mathlive');
|
|
156
|
+
configureLoaded();
|
|
127
157
|
} catch (e) {
|
|
128
|
-
|
|
129
|
-
// the import can fail in test/SSR-ish runtimes. Fail soft: callers all
|
|
130
|
-
// handle a missing instance (static rendering falls back to raw latex).
|
|
131
|
-
log('MathLive could not be loaded: %s', e && e.message);
|
|
158
|
+
log('synchronous MathLive load unavailable: %s', e && e.message);
|
|
132
159
|
return undefined;
|
|
133
160
|
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return mathlive;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Load MathLive. Prefers the synchronous path; falls back to a dynamic import.
|
|
168
|
+
* Resolves to undefined during SSR.
|
|
169
|
+
*
|
|
170
|
+
* @returns {Promise<object|undefined>}
|
|
171
|
+
*/
|
|
172
|
+
export const loadMathLive = async () => {
|
|
173
|
+
if (typeof window === 'undefined') {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (mathlive) {
|
|
178
|
+
return mathlive;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (loadMathLiveSync()) {
|
|
182
|
+
return mathlive;
|
|
183
|
+
}
|
|
134
184
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
185
|
+
try {
|
|
186
|
+
mathlive = await import('mathlive');
|
|
187
|
+
configureLoaded();
|
|
188
|
+
} catch (e) {
|
|
189
|
+
// Surface this once: a silent failure here renders every field and keypad
|
|
190
|
+
// label blank, which is very hard to trace back to a module load.
|
|
191
|
+
// Skipped under test, where jsdom cannot load the browser build.
|
|
192
|
+
if (!loadWarned && process.env.NODE_ENV !== 'test') {
|
|
193
|
+
loadWarned = true;
|
|
194
|
+
// eslint-disable-next-line no-console
|
|
195
|
+
console.warn(
|
|
196
|
+
'[@pie-lib/math-input-mathlive] MathLive could not be loaded; math input will not render. ' +
|
|
197
|
+
'If this is a bundling issue, ensure "mathlive" is resolvable from the host bundle. Cause: ' +
|
|
198
|
+
(e && e.message),
|
|
142
199
|
);
|
|
143
200
|
}
|
|
144
201
|
|
|
145
|
-
|
|
146
|
-
fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);
|
|
202
|
+
return undefined;
|
|
147
203
|
}
|
|
148
204
|
|
|
149
205
|
return mathlive;
|
|
@@ -231,25 +287,39 @@ export const __setMathLiveForTest = (stub) => {
|
|
|
231
287
|
* Render static math into an element. API-compatible with
|
|
232
288
|
* @pie-lib/math-input's `applyStaticMath`.
|
|
233
289
|
*
|
|
290
|
+
* Callers written against MathQuill invoke this synchronously from lifecycle
|
|
291
|
+
* methods, where MathLive (a dynamic import) may not have loaded yet. Rather
|
|
292
|
+
* than silently rendering nothing, this kicks off the load and re-applies once
|
|
293
|
+
* the engine is ready, so the element fills in on the next tick.
|
|
294
|
+
*
|
|
234
295
|
* @param {HTMLElement} element
|
|
235
296
|
* @param {string} [latex] assigned to the element before rendering
|
|
236
297
|
* @param {object} [options] `{ macros }` overrides
|
|
237
|
-
* @returns {HTMLElement|undefined} the element,
|
|
298
|
+
* @returns {HTMLElement|undefined} the element, or undefined if deferred
|
|
238
299
|
*/
|
|
239
300
|
export function applyStaticMath(element, latex, options = {}) {
|
|
240
301
|
if (!element || typeof window === 'undefined') {
|
|
241
302
|
return undefined;
|
|
242
303
|
}
|
|
243
304
|
|
|
244
|
-
|
|
305
|
+
// Capture the source now: if we defer, the element's textContent may have
|
|
306
|
+
// been overwritten by the time MathLive is ready.
|
|
307
|
+
const source = latex === undefined || latex === null ? element.textContent : latex;
|
|
308
|
+
const ml = getMathLive() || loadMathLiveSync();
|
|
245
309
|
|
|
246
310
|
if (!ml) {
|
|
247
|
-
log('applyStaticMath called before MathLive loaded -
|
|
311
|
+
log('applyStaticMath called before MathLive loaded - deferring until it is ready');
|
|
312
|
+
|
|
313
|
+
loadMathLive().then((loaded) => {
|
|
314
|
+
// The element may have been unmounted while loading.
|
|
315
|
+
if (loaded && element.isConnected !== false) {
|
|
316
|
+
applyStaticMath(element, source, options);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
248
320
|
return undefined;
|
|
249
321
|
}
|
|
250
322
|
|
|
251
|
-
const source = latex === undefined || latex === null ? element.textContent : latex;
|
|
252
|
-
|
|
253
323
|
element.innerHTML = ml.convertLatexToMarkup(toMathLive(source), {
|
|
254
324
|
macros: { ...getMacros(), ...(options.macros || {}) },
|
|
255
325
|
});
|
|
@@ -266,7 +336,9 @@ export function applyStaticMath(element, latex, options = {}) {
|
|
|
266
336
|
* @returns {string} HTML markup, or '' if MathLive is not loaded
|
|
267
337
|
*/
|
|
268
338
|
export function latexToMarkup(latex, options = {}) {
|
|
269
|
-
|
|
339
|
+
// Try the synchronous load so the very first render can produce markup
|
|
340
|
+
// instead of falling back to raw latex.
|
|
341
|
+
const ml = getMathLive() || loadMathLiveSync();
|
|
270
342
|
|
|
271
343
|
if (!ml || !latex) {
|
|
272
344
|
return '';
|