mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-10 02:02:29 +08:00
Add preview fix
This commit is contained in:
parent
e6605706c0
commit
b7ccab38ff
@ -64,7 +64,7 @@ export default class MathUI extends Plugin {
|
||||
...this.editor.config.get( 'math' )
|
||||
};
|
||||
|
||||
const formView = new MainFormView( editor.locale, mathConfig.engine );
|
||||
const formView = new MainFormView( editor.locale, mathConfig.engine, mathConfig.enablePreview );
|
||||
|
||||
formView.mathInputView.bind( 'value' ).to( mathCommand, 'value' );
|
||||
formView.displayButtonView.bind( 'isOn' ).to( mathCommand, 'display' );
|
||||
@ -106,6 +106,13 @@ export default class MathUI extends Plugin {
|
||||
this._form.mathInputView.select();
|
||||
}
|
||||
|
||||
// Show preview element
|
||||
const elId = 'math-preview';
|
||||
let prewviewEl = document.getElementById( elId );// eslint-disable-line
|
||||
if ( prewviewEl ) {
|
||||
prewviewEl.style.display = 'block';
|
||||
}
|
||||
|
||||
this._form.equation = mathCommand.value || '';
|
||||
this._form.displayButtonView.isOn = mathCommand.display || false;
|
||||
}
|
||||
@ -141,6 +148,13 @@ export default class MathUI extends Plugin {
|
||||
|
||||
this._balloon.remove( this._form );
|
||||
|
||||
// Hide preview element
|
||||
const elId = 'math-preview';
|
||||
let prewviewEl = document.getElementById( elId );// eslint-disable-line
|
||||
if ( prewviewEl ) {
|
||||
prewviewEl.style.display = 'none';
|
||||
}
|
||||
|
||||
this.editor.editing.view.focus();
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import MathView from './mathview';
|
||||
import '../../theme/mathform.css';
|
||||
|
||||
export default class MainFormView extends View {
|
||||
constructor( locale, engine ) {
|
||||
constructor( locale, engine, previewEnabled ) {
|
||||
super( locale );
|
||||
|
||||
const t = locale.t;
|
||||
@ -33,10 +33,6 @@ export default class MainFormView extends View {
|
||||
// Equation input
|
||||
this.mathInputView = this._createMathInput();
|
||||
|
||||
// Fixme:
|
||||
// Preview isn't available in katex, because .ck-reset_all * css rule breaks it
|
||||
this.previewEnabled = engine !== 'katex' || true;
|
||||
|
||||
// Display button
|
||||
this.displayButtonView = this._createDisplayButton();
|
||||
|
||||
@ -47,11 +43,12 @@ export default class MainFormView extends View {
|
||||
// Cancel button
|
||||
this.cancelButtonView = this._createButton( t( 'Cancel' ), cancelIcon, 'ck-button-cancel', 'cancel' );
|
||||
|
||||
// Preview label
|
||||
this.previewLabel = new LabelView( locale );
|
||||
this.previewEnabled = previewEnabled;
|
||||
|
||||
let children = [];
|
||||
if ( this.previewEnabled ) {
|
||||
// Preview label
|
||||
this.previewLabel = new LabelView( locale );
|
||||
this.previewLabel.text = t( 'Equation preview' );
|
||||
|
||||
// Math element
|
||||
@ -65,11 +62,9 @@ export default class MainFormView extends View {
|
||||
this.mathView
|
||||
];
|
||||
} else {
|
||||
this.previewLabel.text = t( 'Equation preview isn\'t available' );
|
||||
children = [
|
||||
this.mathInputView,
|
||||
this.displayButtonView,
|
||||
this.previewLabel
|
||||
this.displayButtonView
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ export default class MathView extends View {
|
||||
} );
|
||||
|
||||
this.setTemplate( {
|
||||
tag: 'iframe',
|
||||
tag: 'div',
|
||||
attributes: {
|
||||
class: [
|
||||
'ck',
|
||||
@ -29,40 +29,7 @@ export default class MathView extends View {
|
||||
updateMath() {
|
||||
const el = this.element;
|
||||
if ( el ) {
|
||||
// Fixme
|
||||
// eslint-disable-next-line
|
||||
setTimeout( () => {
|
||||
let docEl = ( el.contentWindow || el.contentDocument );
|
||||
if ( docEl.document ) {
|
||||
docEl = docEl.document;
|
||||
}
|
||||
|
||||
const headEl = docEl.head;
|
||||
|
||||
// Remove old styles
|
||||
while ( headEl.hasChildNodes() ) {
|
||||
headEl.removeChild( headEl.firstChild );
|
||||
}
|
||||
|
||||
// Add all MathJax styles
|
||||
const styles = document.head.getElementsByTagName( 'style' ); // eslint-disable-line
|
||||
for ( const style of styles ) {
|
||||
const id = style.getAttribute( 'id' );
|
||||
if ( id && id.startsWith( 'MJX' ) ) {
|
||||
headEl.appendChild( style.cloneNode( true ) );
|
||||
}
|
||||
}
|
||||
|
||||
const links = document.head.getElementsByTagName( 'link' ); // eslint-disable-line
|
||||
for ( const link of links ) {
|
||||
headEl.appendChild( link.cloneNode( true ) );
|
||||
}
|
||||
|
||||
const bodyEl = docEl.body;
|
||||
bodyEl.setAttribute( 'style', 'margin-left: 0; margin-right: 0; user-select: none;' );
|
||||
|
||||
renderEquation( this.value, bodyEl, this.engine, this.display );
|
||||
}, 100 );
|
||||
renderEquation( this.value, el, this.engine, this.display, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
149
src/utils.js
149
src/utils.js
@ -1,7 +1,8 @@
|
||||
export const defaultConfig = {
|
||||
engine: 'mathjax',
|
||||
outputType: 'script',
|
||||
forceOutputType: false
|
||||
forceOutputType: false,
|
||||
enablePreview: true
|
||||
};
|
||||
|
||||
export function getSelectedMathModelWidget( selection ) {
|
||||
@ -14,47 +15,30 @@ export function getSelectedMathModelWidget( selection ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function renderEquation( equation, element, engine = 'katex', display = false ) {
|
||||
export function renderEquation( equation, element, engine = 'katex', display = false, previewHack = false ) {
|
||||
if ( engine === 'mathjax' && typeof MathJax !== 'undefined' ) {
|
||||
if ( isMathJaxVersion3( MathJax.version ) ) {
|
||||
const options = MathJax.getMetricsFor( element, display );
|
||||
let promiseFunction = undefined;
|
||||
if ( typeof MathJax.tex2chtmlPromise !== 'undefined' ) {
|
||||
promiseFunction = MathJax.tex2chtmlPromise;
|
||||
} else if ( typeof MathJax.tex2svgPromise !== 'undefined' ) {
|
||||
promiseFunction = MathJax.tex2svgPromise;
|
||||
}
|
||||
|
||||
if ( typeof promiseFunction !== 'undefined' ) {
|
||||
promiseFunction( equation, options ).then( node => {
|
||||
if ( element.firstChild ) {
|
||||
element.firstChild.replaceWith( node );
|
||||
} else {
|
||||
element.appendChild( node );
|
||||
selectRenderMode( element, previewHack, el => {
|
||||
renderMathJax3( equation, el, display, () => {
|
||||
if ( previewHack ) {
|
||||
moveAndScaleElement( element, el );
|
||||
}
|
||||
MathJax.startup.document.clear();
|
||||
MathJax.startup.document.updateDocument();
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
// Fixme: MathJax typesetting cause occasionally math processing error without asynchronous call
|
||||
// eslint-disable-next-line
|
||||
setTimeout( () => {
|
||||
if ( display ) {
|
||||
element.innerHTML = '\\[' + equation + '\\]';
|
||||
} else {
|
||||
element.innerHTML = '\\(' + equation + '\\)';
|
||||
}
|
||||
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, element ] ); // eslint-disable-line
|
||||
selectRenderMode( element, previewHack, el => {
|
||||
renderMathJax2( equation, el, display );
|
||||
} );
|
||||
}
|
||||
} else if ( engine === 'katex' && typeof katex !== 'undefined' ) {
|
||||
katex.render( equation, element, {
|
||||
throwOnError: false,
|
||||
displayMode: display
|
||||
selectRenderMode( element, previewHack, el => {
|
||||
katex.render( equation, el, {
|
||||
throwOnError: false,
|
||||
displayMode: display
|
||||
} );
|
||||
} );
|
||||
} else if ( typeof engine === 'function' ) {
|
||||
engine( equation, element, display );
|
||||
engine( equation, element, display, previewHack );
|
||||
} else {
|
||||
element.innerHTML = equation;
|
||||
// eslint-disable-next-line
|
||||
@ -62,6 +46,107 @@ export function renderEquation( equation, element, engine = 'katex', display = f
|
||||
}
|
||||
}
|
||||
|
||||
function selectRenderMode( element, preview, cb ) {
|
||||
if ( preview ) {
|
||||
createPreviewElement( element, prewviewEl => {
|
||||
cb( prewviewEl );
|
||||
} );
|
||||
} else {
|
||||
cb( element );
|
||||
}
|
||||
}
|
||||
|
||||
function renderMathJax3( equation, element, display, after ) {
|
||||
const options = MathJax.getMetricsFor( element, display );
|
||||
let promiseFunction = undefined;
|
||||
if ( typeof MathJax.tex2chtmlPromise !== 'undefined' ) {
|
||||
promiseFunction = MathJax.tex2chtmlPromise;
|
||||
} else if ( typeof MathJax.tex2svgPromise !== 'undefined' ) {
|
||||
promiseFunction = MathJax.tex2svgPromise;
|
||||
}
|
||||
|
||||
if ( typeof promiseFunction !== 'undefined' ) {
|
||||
promiseFunction( equation, options ).then( node => {
|
||||
if ( element.firstChild ) {
|
||||
element.firstChild.replaceWith( node );
|
||||
} else {
|
||||
element.appendChild( node );
|
||||
}
|
||||
MathJax.startup.document.clear();
|
||||
MathJax.startup.document.updateDocument();
|
||||
after();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
function renderMathJax2( equation, element, display ) {
|
||||
// Fixme: MathJax typesetting cause occasionally math processing error without asynchronous call
|
||||
// eslint-disable-next-line
|
||||
setTimeout( () => {
|
||||
if ( display ) {
|
||||
element.innerHTML = '\\[' + equation + '\\]';
|
||||
} else {
|
||||
element.innerHTML = '\\(' + equation + '\\)';
|
||||
}
|
||||
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, element ] ); // eslint-disable-line
|
||||
} );
|
||||
}
|
||||
|
||||
function createPreviewElement( element, render ) {
|
||||
const prewviewEl = getPreviewElement( element );
|
||||
render( prewviewEl );
|
||||
moveAndScaleElement( element, prewviewEl );
|
||||
}
|
||||
|
||||
export function getPreviewElement( element ) {
|
||||
const elId = 'math-preview';
|
||||
let prewviewEl = document.getElementById( elId ); // eslint-disable-line
|
||||
if ( !prewviewEl ) {
|
||||
prewviewEl = document.createElement( 'div' ); // eslint-disable-line
|
||||
prewviewEl.setAttribute( 'id', elId );
|
||||
document.body.appendChild( prewviewEl ); // eslint-disable-line
|
||||
|
||||
let ticking = false;
|
||||
|
||||
const renderTransformation = () => {
|
||||
if ( !ticking ) {
|
||||
// eslint-disable-next-line
|
||||
window.requestAnimationFrame( () => {
|
||||
moveElement( element, prewviewEl );
|
||||
ticking = false;
|
||||
} );
|
||||
|
||||
ticking = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Create scroll listener for following
|
||||
window.addEventListener( 'resize', renderTransformation ); // eslint-disable-line
|
||||
window.addEventListener( 'scroll', renderTransformation ); // eslint-disable-line
|
||||
}
|
||||
return prewviewEl;
|
||||
}
|
||||
|
||||
function moveAndScaleElement( parent, element ) {
|
||||
moveElement( parent, element );
|
||||
|
||||
// Scale parent element same as preview
|
||||
const domRect = element.getBoundingClientRect();
|
||||
// element.style.width = domRect.width + 'px';
|
||||
parent.style.height = domRect.height + 'px';
|
||||
}
|
||||
|
||||
function moveElement( parent, element ) {
|
||||
const domRect = parent.getBoundingClientRect();
|
||||
const left = window.scrollX + domRect.left; // eslint-disable-line
|
||||
const top = window.scrollY + domRect.top; // eslint-disable-line
|
||||
element.style.position = 'absolute';
|
||||
element.style.left = left + 'px';
|
||||
element.style.top = top + 'px';
|
||||
element.style.zIndex = 'var(--ck-z-modal)';
|
||||
element.style.pointerEvents = 'none';
|
||||
}
|
||||
|
||||
// Simple MathJax 3 version check
|
||||
export function isMathJaxVersion3( version ) {
|
||||
return version && typeof version === 'string' && version.split( '.' ).length === 3 && version.split( '.' )[ 0 ] === '3';
|
||||
|
@ -6,12 +6,6 @@
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
& .ck.ck-math-preview {
|
||||
/* Todo: calculate content size */
|
||||
width: 234px;
|
||||
height: 10em;
|
||||
}
|
||||
|
||||
@mixin ck-media-phone {
|
||||
flex-wrap: wrap;
|
||||
|
||||
@ -32,3 +26,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Increase toolbar default z-index by one because math preview should be below of it
|
||||
.ck.ck-toolbar-container {
|
||||
z-index: calc(var(--ck-z-modal) + 2);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user