import { resetInputSize } from 'src/lib/mathquill/functions'
import VirtualKeyboard from 'src/lib/widgets/mlVirtualKeyboard/VirtualKeyboard'
import Button from './Button'
function insertTextAtCursor (element, text) {
const startPos = element.selectionStart
const endPos = element.selectionEnd
element.value = element.value.substring(0, startPos) + text + element.value.substring(endPos, element.value.length)
element.selectionStart = element.selectionEnd = startPos + text.length
}
class ButtonChar extends Button {
/**
* Créé un <button> rattaché à un input mathquill. Avec une value et sans onClick ça crée le onClick qui ajoutera la value dans l’input
* @param {HTMLElement} editor L’éditeur Mathlive ou le input associé au clavier virtuel contenant le bouton
* @param {HTMLSpanElement} editor L’input Mathfield (un span.mq-editable-field)
* @param {ButtonOptions} options
*/
constructor (editor, options = {}) {
let { onClick, value } = options
const text = editor.tagName.toLowerCase() === 'input'
// Simule un événement keyup qui ne fait rien, au cas où le champ serait marqué en rouge à la suite d’une erreur (pour retirer cette marque)
if (onClick) {
options.onClick = onClick
} else if (value) {
// on crée un listener qui ajoute la value dans l’input
if (text) {
options.onClick = () => {
const input = VirtualKeyboard.currentEditor
if (input === this.editor) {
if (input.demarqueErreur) input.demarqueErreur() // Si on a affecté à l’éditeur une fonction pour le démarquer comme avec erreur
insertTextAtCursor(input, value)
resetInputSize(input)
}
}
} else {
options.onClick = () => {
const mf = VirtualKeyboard.currentEditor
if (mf === this.editor) {
if (mf.demarqueErreur) mf.demarqueErreur() // Si on a affecté à l’éditeur une fonction pour le démarquer comme avec erreur
if (value === '.') value = ','
// toujours feedback à false, ça génère des tonnes d’erreurs `Can’t find variable: AudioContext`
// et c’est pas souhaitable de faire du bruit…
// par ailleurs ce truc plante de temps à autre avec TypeError `Cannot read properties of undefined (reading 'type')`
try {
mf.executeCommand(['typedText', value, { feedback: false, focus: false, simulateKeystroke: true }])
} catch (error) {
console.error(error)
}
}
}
}
}
// Pour les lettes minuscumes on utilise la police Giorgia avec italique
if (value?.length === 1 && /[a-z]/g.test(value)) options.className = 'mlBtnLetter' // pour que les lettres soient en italiques
super(editor, options)
}
/**
* Ajoute un bouton dans container
* @param {HTMLElement} container
* @param {mathfield} mathfiel L’éditeur mathfield associé
* @param {ButtonOptions} options
*/
static addInto (container, mathfield, options) {
// on est une méthode statique, this fait référence à la classe elle-même
// ne pas mettre ici ButtonMq mais this permet de faire fonctionner ça pour toutes les classes qui étendent ButtonMq
const btn = new this(mathfield, options)
container.appendChild(btn.element)
}
}
export default ButtonChar