arnog / mathlive

A web component for easy math input
https://cortexjs.io/mathlive
MIT License
1.56k stars 277 forks source link

Feature Request: Improved "insert" command #2432

Closed andrew-murdza closed 3 months ago

andrew-murdza commented 3 months ago

Currently, insert has the format mf.executeCommand(["insert", "(#0)"]); which allows for adding stuff before and after the selection.

I would like it to support something like mf.executeCommand(["insert", f]); where f is a javascript function that turns a string into a string. For example, mf.executeCommand(["insertFunction", x=>x.replaceAll('\frac','\powfrac')]); would turn 1+\frac{1}{2} into 1+\powfrac{1}{2}

arnog commented 3 months ago

Is this something triggered by a keycap on the virtual keyboard? If so, you can use a dispatchEvent command to do this.

Its first argument is the name of the dispatched event, and the second argument is an object with the detail property, which is the data associated with the event.

    { 
      label: "✨",
      command: "dispatchEvent('customEvent', {detail: 'some data'})"
    }

In the customEvent handler, you can access the selection, manipulate if desired, and replace it.

andrew-murdza commented 3 months ago

It would be a keycap, menu option, and, if possible, an external button being pressed. If it works for those cases, then that works. Is there a place where I can read about how "detail" works? I can't find customEvent in the documentation. Basically how you can access the selection and replace it (I know how to manipulate it)

arnog commented 3 months ago

customEvent is a string of your choosing. It's the name of the event you can listen to. detail is an optional property you can populate with whatever you want. It's the standard property for custom events in JavaScript.

andrew-murdza commented 3 months ago

Is 'customEvent' equivalent to the contents of onclick="...?" For example are "dispatchEvent('this.innerHTML = Date()', {detail: 'some data'})" the same as button onclick="this.innerHTML = Date()"?

arnog commented 3 months ago

This is just using the standard web platform events. You can learn more about them here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

So, let's say you want to have a keycap that turns "\frac" into "\powfrac". You would setup a keycap like so:

  { 
    label: "✨",
    command: "dispatchEvent('convert-to-powfrac')"
  }

Pressing the keycap will cause a convert-to-powfrac event to be dispatched.

Then in your document, you would attach an event handler like so:

mathVirtualKeyboard.addEventListener('conver-to-powfrac', (evt) => {
  const mf = evt.target;
  let selection = mf.getValue(mf.selection);
  selection = selection.replaceAll('\frac','\powfrac')]);
  mf.insert(selection);
});
andrew-murdza commented 3 months ago

I see! You can close this now.