AutorÃa | Ultima modificación | Ver Log |
// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Equation helper for Tiny Equation plugin.** @module tiny_equation/equation* @copyright 2022 Huong Nguyen <huongnv13@gmail.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/import Selectors from 'tiny_equation/selectors';let sourceEquation = null;/*** Get the source equation.* @returns {Object}*/export const getSourceEquation = () => sourceEquation;/*** Get selected equation.* @param {TinyMCE} editor* @returns {boolean}*/export const getSelectedEquation = (editor) => {const currentSelection = editor.selection.getSel();if (!currentSelection) {// Do the early return if there is no text selected.return false;}const textSelection = editor.selection.getNode().textContent;const currentCaretPos = currentSelection.focusOffset;let returnValue = false;Selectors.equationPatterns.forEach((pattern) => {// For each pattern in turn, find all whole matches (including the delimiters).const regexPattern = new RegExp(pattern.source, "g");[...textSelection.matchAll(regexPattern)].forEach((matches) => {const match = matches[0];// Check each occurrence of this match.let startIndex = 0;const startOuter = textSelection.indexOf(match, startIndex);const endOuter = startOuter + match.length;// This match is in our current position - fetch the innerMatch data.const innerMatch = match.match(pattern);if (innerMatch && innerMatch.length) {// We need the start and end of the inner match for later.const startInner = textSelection.indexOf(innerMatch[1], startOuter);const endInner = startInner + innerMatch[1].length;// We need to check the caret position before returning the match.if (currentCaretPos >= startOuter && currentCaretPos <= endOuter) {// We'll be returning the inner match for use in the editor itself.returnValue = innerMatch[1];// Save all data for later.sourceEquation = {// Inner match data.startInnerPosition: startInner,endInnerPosition: endInner,innerMatch: innerMatch};return;}}// Update the startIndex to match the end of the current match so that we can continue hunting// for further matches.startIndex = endOuter;});});// We trim the equation when we load it and then add spaces when we save it.if (returnValue !== false) {returnValue = returnValue.trim();} else {// Clear the saved source equation.sourceEquation = null;}return returnValue;};/*** Get current equation data.* @param {TinyMCE} editor* @returns {{}}*/export const getCurrentEquationData = (editor) => {let properties = {};const equation = getSelectedEquation(editor);if (equation) {properties.equation = equation;}return properties;};/*** Handle insertion of a new equation, or update of an existing one.* @param {Element} currentForm* @param {TinyMCE} editor*/export const setEquation = (currentForm, editor) => {const input = currentForm.querySelector(Selectors.elements.equationTextArea);const sourceEquation = getSourceEquation();let value = input.value;if (value !== '') {if (sourceEquation) {const selectedNode = editor.selection.getNode();const text = selectedNode.textContent;value = ' ' + value + ' ';selectedNode.textContent = text.slice(0, sourceEquation.startInnerPosition)+ value+ text.slice(sourceEquation.endInnerPosition);} else {value = Selectors.delimiters.start + ' ' + value + ' ' + Selectors.delimiters.end;editor.insertContent(value);}}};