Plugin for Fidus Writer

Hey guys, great work!

I have written a (still very simple) plugin for Fidus Writer, the open source semantic editor for academics (because it has citation management, export to LaTeX, etc.). The code for the plugin is here: GitHub - fiduswriter/fiduswriter-languagetool . We will release version 3.3 of fidus Writer in the next few weeks, and that’s the version the plugin will work with. Please let me know what you think and if something else needs to be added.

Hey, It seems like Fidus Writer is based on content editable right?

Reason I ask is I’ve been working on a TinyMCE4 plugin which I then made a bit more modular for those who wanted to implement it on other contenteditable editors. I implemented a bunch of advanced features and customization already (thought it is based on jquery since I’ve been trying for some backwards compatibility while I see you’ve targeted ES6). Not sure if it makes sense to work together to modularize it more to make it work with everything while retaining all features.

(If not, then maybe the code or ideas already implemented will come useful either way as you work on yours)

Hey,
thanks for the offer! It’s always a good idea to work together and look at each others work. I am also helping on improving the various contenteditable specs [1]. Unfortunately, it is currently not recommended to make changes directly to the contenteditable, but instead to use a model in-between. So basically modern editors work like this:

  1. user makes input
  2. document model is updated
  3. DOM is updated to be in line with document model

To assist in this, we made the beforeinput-event [2] where the JavaScript receives a notification that the user would like to change something. This has shipped in Safari and Chrome thus far.

Why is it not recommended to directly do everything in contenteditable the way the older versions of TinyMCE or CKEditor did? Because contenteditable is both buggy and implemented slightly differently in every browser, so what these editors did was “tweak” how the input was treated, at times modifying the DOM after the fact at times canceling the event that lead to the change. This was all fairly similar to today’s way of doing it, but without the added benefit of having a model of the document to base it on.

Plugins that just operate on the DOM themselves without “knowledge” of the editor in question make the picture even more complex. For example, there used to be a Grammarly-plugin that people installed directly into Chrome. And it crashed both TinyMCE and CKEditor and probably most other editors, apparently without the Grammarly developers ever finding out.

So in short: Fidus Writer is using contenteditable, true, but unfortunately it will be incompatible with any plugin that will try to directly modify the DOM. It does use the ProseMirror for the model and DOM in/output, so part of the code could be reused by other editors using the ProseMirror-library. In case there are other editors willing to help, we could split out one part that directly interacts with ProseMirror and license that part LGPL.

[1] GitHub - w3c/editing: Specs and explainers maintained by the editing task force
[2] GitHub - w3c/input-events: Input Events

1 Like

Thanks, I’ve added it to the list of LT add-ons.

1 Like

Well what I have been trying to do as part of making it modular was instead split up the logic from the actual editor modification. So effectively, you just rewrite events that are then called from the central module. In this way, every editor’s plugin will decide for itself how it wants to do things like edit the DOM or how it wants to process things.

I kind of want to focus on flexibility such as limit how much data is sent to the server by doing things like monitoring changes and the like. If a person has to send a 500 page essay every time to the LT server, it would get crowded quick. So I’ve been trying to implement a priority based queuing system and things like rendering spelling/grammar for viewport only and processing more as the user scrolls.

You can look at some of the features I implemented and see if they make sense for you or not. (even if it is just to replicate them in another way)

So what I am saying is that yes, contenteditable is being used at the lowest level, but the ProseMirror library is flushing the DOm constantly and changing it, so there is no way I can do anything directly on the DOM (within the editor). All the changes I do have to go through the ProseMirror-model and prosemirror then turns it into DOM-updates.
In this case, for example, it allows something called “inline decorations”, where I basically can say that from character 8 to 15, I want to have a decoration, and I can add a CSS class or some styling to that. ProseMirror then takes care of updating the position of this decoration as the document updates (for example if the user types some at the beginning of the text, the numbers will be higher than characters 8 to 15, etc.).

All the editors are moving to such a model, as far as I know, so directly manipulating the DOM will not work going forward. Instead one needs to write quite different plugins that work with the different models and update methods that the editors offer – at least until we get the beforeinput event.

I looked a bit at the other things you mention. If we implement continuous checking, we will also need to do something like this (but we cannot check the DOM for text but instead need to look at the model provided through ProseMirror to find out what has changed. And because we don’t get it from the DOM, it’s not as easy to find out what part is currently visible for the user (but should not be impossible).

As for backgorund SVG for underlining – we don’t currently allow underlining, so we don’t have a conflict. Also, ProseMirror only allows specification of CSS classes or style attributed. Adding background SVG, etc. without messing with the part of the DOM controlled by ProseMirror and making sure that it alwasy stays in place correctly would have to be implemented in a ProseMirror-specific way.

So if you do something like:

  background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 4 3" height="3" width="4" fill="%23FF0000"><path d="M 0.29035517,1.4291044 C -0.92396403,-0.1192701 -0.38579998,-0.33810181 0.58454674,0.90550316 2.2240533,3.0067093 2.3955445,2.3505447 3.5620362,1.241324 4.0021271,0.82284017 4.4297825,0.77891784 4.0341445,1.4664179 3.104357,3.0821083 1.9261285,3.5148733 0.29035517,1.4291044 Z" /></svg>') 50% 100% repeat-x transparent;padding-bottom:0;display:inline

It won’t work?

ah you mean directly as a CSS property? I guess that should be doable. Thanks for that, I did not realize one could do that.

However, as we currently don’t use text decorations, but we do use background-color for some other things (comments), this probably wouldn’t make much sense for us right now. But there may be other things you are working on that could be more interesting for us. Your strategies for dealing with continuous text input will be interesting to look at, for example.

The above code does not conflict with background-color, at least not on Chrome or FF. But since you don’t use text-decoration I guess it doesn’t matter too much other than the familiar like wavy line is probably only advantage.

1 Like

Ok, we may come back to it then. I noticed that Chrome at least also supports wavy line text -decorations, but it didn’t look as good as the dots because it wouldn’t go under the entire word for some reason…

@KnowZero You mentioned Chrome and FF. Have you tried it out on Safari and Edge? I am trying to figure out which way of underlining has the broadest support among browsers.

I was going to answer yes to Edge because it should have on paper. But then just in case I VMd a windows instance and tried Edge and as expected of MS, apparently it’s picky about the quotes you use. Here is an Edge compatible:

 background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' viewBox='0 0 4 3' height='3' width='4' fill='%23FF0000'><path d='M 0.29035517,1.4291044 C -0.92396403,-0.1192701 -0.38579998,-0.33810181 0.58454674,0.90550316 2.2240533,3.0067093 2.3955445,2.3505447 3.5620362,1.241324 4.0021271,0.82284017 4.4297825,0.77891784 4.0341445,1.4664179 3.104357,3.0821083 1.9261285,3.5148733 0.29035517,1.4291044 Z' /></svg>") 50% 100% repeat-x transparent;padding-bottom:0;display:inline

I don’t have access to a machine with Safari right now unfortunately.

I did a test on the old Windows version of Safari 5.1 and it worked there, considering it also works on Chrome there probably is no issue.

Edit:

Also tried a screenshot browser service and Safari 9.1 came out fine too.

You can probably get real interactive testing for free at https://saucelabs.com/open-source.

2 Likes

Yeah, we usually use saucelabs. On Safari I can get the background-property to work, but -webkit-text-decoration: underline wavy red; also works, so we on’t really need it. On Edge I cannot get any of them to work.

You can’t get text decoration to work on Edge? Or you can’t get the updated code I posted to work?

I cannot get either of them to work on edge.

Even after trying the updated code?

Here is my results from the VM:

Sorry, I had somehow missed the message on updated edge code. Yes, that works.

@dnaber: In the text I send in for checking, is there some ay to mark that there is a character in a location that should now be checked? For example, if we have a have a formula in a sentence like this:

"This is a sentence <formula>."

I simply replaced the formula with a space. This works, but it returns a double space error. Is there some other control character I could replace he formula with?