How to load custom css everytime note renders

Hey,
I was able to make plugin for "Keyboard shortcut for editor font size" thanks to guidance of @CalebJohn . Discussion of this topic can be found here. Here's the Plugin Link. But there is one problem right now:

Thanks!

Joplin reloads the css every time a note is loaded so you would need to apply any change you make again.

But aren't there a CodeMirror hook that can be used to set the options, possibly including the font size? I think that's used by the plugin that adds the line numbers.

Yes, I wanted to do the same by applying CSS again when we get 'noteRenderComplete' message but could not find a way to access this through plugin.

There isn't a separate option for font size but I will try adding it through 'theme' option.

The codemirror theme option controls the css class applied to items in the editor. It won't help you here unless you want to get really tricky (but we should be able to find a better solution).


Fortunately, the solution for you problem is pretty simple.
tl;dr: When Joplin exits the editor it re-adds the custom css to the document. This means it takes priority for styling. You can force your font size styling to always take priority by adding !important.

If you have the time, I have a few cool things to show you.

Inspecting the html/css

When you add css to Joplin via loadChromeCSSFile it is adding a <style> tag within the <head> block of the document. (Look right at the bottom thats your plugin!)
image

Here it is after pressing the increase font size button a couple times (Looks like there are some duplicates, I'll leave that up to you to diagnose/fix).
image

Finally, If you leave the note (go to settings) and come back, you'll see that the codemirror styles are added below yours. (This is because the codemirror styles are removed when the editor is closed, and added back when it is opened)
image

This is what is causing your issue. Your CSS is sustained, it's just that the priority is now lower than the codemirror css. To overcome this you can add !important to your css which will make your font-size take priority.

You can remove the onChange and onNoteChange events because they don't do anything for your plugin (I suspect you added them while trying to fix your issue above).

BTW, I read through your source and it has a lot of code duplication. I would encourage you to review it (after you make these changes) and try to identify where you are duplicating code. I'd like to see it again once you do. This is shaping up to be a very nice plugin!

Extra

CodeMirror refresh

I noticed that you are replacing the entire body of the note in order to get the editor to refresh. That's a neat trick, but ultimately it's just calling into codemirror.refresh() which is what you need to do after changing the CSS. Joplin provides a command to do this (kinda), using editor.execCommand.
If you apply it to your code (see below), you'll see that the font size changing is much smoother!

-        let newNoteBody = note.body;
-        await joplin.commands.execute("textSelectAll");
-        await joplin.commands.execute("replaceSelection", newNoteBody);
+        await joplin.commands.execute('editor.execCommand', {
+            name: 'refresh',
+            args: [],
+        });
4 Likes

Wow!!! Thanks a lot CalebJohn for the detailed explanation,

Always up for cool things :grin:

I had added this previously, but don't know why I removed it. No problem, I will try it out.

I agree that code can be more cleaner. I will definitely notify you after making changes. I hope I am not bothering you with this.

Yayyyy! Its working with !important . Now I just need to clean the code.

1 Like

Hey @CalebJohn ,

I refactored the code as it had code duplication as you suggested.

I added one additional feature of 'Change Factor'. It defines by how much size we should increase/decrease font size.

To fix this I added a function to compare local CSS and newly generated one and only load it if both doesn't match but unfortunately its not working. Spent hours trying to fix this but no luck. I suspect this maybe caused by async function somewhere.
Maybe I have to extract the font size from the local CSS with Regex and then compare. I will try to fix this again.

codemirror.refresh() worked like charm :slight_smile:, its very smooth now!

You said you wanted to view it again so here's the Link.

Thanks

1 Like

It's looking a lot better!

There is still considerable overlap between executeFontChange and compareCSSAndApply, writeAndLoadCSS, cssFromCustomValue. I bet solving this duplication will solve the duplicate additions without the need for comparing css...

I encourage you to carefully read through your code and observe where the CSS is being applied.

Hint: Calling joplin.settings.setValue triggers joplin.settings.onChange

1 Like

Thanks for taking time to review it.

Yep, I noticed this and also tried running plugin without onChange function. No problem, I will try again!